Commit 5012aada authored by Stefan Achatz's avatar Stefan Achatz Committed by Jiri Kosina

HID: roccat: use class for char device for sysfs attribute creation

Adding sysfs attributes to an already created device raises no userland
notification. Now the device drivers associate the devices attributes
with a class and use this for roccat event char device creation.
Signed-off-by: default avatarStefan Achatz <erazor_de@users.sourceforge.net>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent c97415a7
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#include "hid-roccat.h" #include "hid-roccat.h"
#include "hid-roccat-kone.h" #include "hid-roccat-kone.h"
/* kone_class is used for creating sysfs attributes via roccat char device */
static struct class *kone_class;
static void kone_set_settings_checksum(struct kone_settings *settings) static void kone_set_settings_checksum(struct kone_settings *settings)
{ {
uint16_t checksum = 0; uint16_t checksum = 0;
...@@ -261,7 +264,8 @@ static int kone_get_firmware_version(struct usb_device *usb_dev, int *result) ...@@ -261,7 +264,8 @@ static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj, static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
struct bin_attribute *attr, char *buf, struct bin_attribute *attr, char *buf,
loff_t off, size_t count) { loff_t off, size_t count) {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev =
container_of(kobj, struct device, kobj)->parent->parent;
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
if (off >= sizeof(struct kone_settings)) if (off >= sizeof(struct kone_settings))
...@@ -285,7 +289,8 @@ static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj, ...@@ -285,7 +289,8 @@ static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj, static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
struct bin_attribute *attr, char *buf, struct bin_attribute *attr, char *buf,
loff_t off, size_t count) { loff_t off, size_t count) {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev =
container_of(kobj, struct device, kobj)->parent->parent;
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
int retval = 0, difference; int retval = 0, difference;
...@@ -321,7 +326,8 @@ static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj, ...@@ -321,7 +326,8 @@ static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
static ssize_t kone_sysfs_read_profilex(struct kobject *kobj, static ssize_t kone_sysfs_read_profilex(struct kobject *kobj,
struct bin_attribute *attr, char *buf, struct bin_attribute *attr, char *buf,
loff_t off, size_t count, int number) { loff_t off, size_t count, int number) {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev =
container_of(kobj, struct device, kobj)->parent->parent;
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
if (off >= sizeof(struct kone_profile)) if (off >= sizeof(struct kone_profile))
...@@ -371,7 +377,8 @@ static ssize_t kone_sysfs_read_profile5(struct file *fp, struct kobject *kobj, ...@@ -371,7 +377,8 @@ static ssize_t kone_sysfs_read_profile5(struct file *fp, struct kobject *kobj,
static ssize_t kone_sysfs_write_profilex(struct kobject *kobj, static ssize_t kone_sysfs_write_profilex(struct kobject *kobj,
struct bin_attribute *attr, char *buf, struct bin_attribute *attr, char *buf,
loff_t off, size_t count, int number) { loff_t off, size_t count, int number) {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev =
container_of(kobj, struct device, kobj)->parent->parent;
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
struct kone_profile *profile; struct kone_profile *profile;
...@@ -432,14 +439,16 @@ static ssize_t kone_sysfs_write_profile5(struct file *fp, struct kobject *kobj, ...@@ -432,14 +439,16 @@ static ssize_t kone_sysfs_write_profile5(struct file *fp, struct kobject *kobj,
static ssize_t kone_sysfs_show_actual_profile(struct device *dev, static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone =
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile); return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile);
} }
static ssize_t kone_sysfs_show_actual_dpi(struct device *dev, static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone =
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi); return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi);
} }
...@@ -447,11 +456,15 @@ static ssize_t kone_sysfs_show_actual_dpi(struct device *dev, ...@@ -447,11 +456,15 @@ static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
static ssize_t kone_sysfs_show_weight(struct device *dev, static ssize_t kone_sysfs_show_weight(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone;
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); struct usb_device *usb_dev;
int weight = 0; int weight = 0;
int retval; int retval;
dev = dev->parent->parent;
kone = hid_get_drvdata(dev_get_drvdata(dev));
usb_dev = interface_to_usbdev(to_usb_interface(dev));
mutex_lock(&kone->kone_lock); mutex_lock(&kone->kone_lock);
retval = kone_get_weight(usb_dev, &weight); retval = kone_get_weight(usb_dev, &weight);
mutex_unlock(&kone->kone_lock); mutex_unlock(&kone->kone_lock);
...@@ -464,14 +477,16 @@ static ssize_t kone_sysfs_show_weight(struct device *dev, ...@@ -464,14 +477,16 @@ static ssize_t kone_sysfs_show_weight(struct device *dev,
static ssize_t kone_sysfs_show_firmware_version(struct device *dev, static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone =
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version); return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version);
} }
static ssize_t kone_sysfs_show_tcu(struct device *dev, static ssize_t kone_sysfs_show_tcu(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone =
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu); return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu);
} }
...@@ -503,11 +518,15 @@ static int kone_tcu_command(struct usb_device *usb_dev, int number) ...@@ -503,11 +518,15 @@ static int kone_tcu_command(struct usb_device *usb_dev, int number)
static ssize_t kone_sysfs_set_tcu(struct device *dev, static ssize_t kone_sysfs_set_tcu(struct device *dev,
struct device_attribute *attr, char const *buf, size_t size) struct device_attribute *attr, char const *buf, size_t size)
{ {
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone;
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); struct usb_device *usb_dev;
int retval; int retval;
unsigned long state; unsigned long state;
dev = dev->parent->parent;
kone = hid_get_drvdata(dev_get_drvdata(dev));
usb_dev = interface_to_usbdev(to_usb_interface(dev));
retval = strict_strtoul(buf, 10, &state); retval = strict_strtoul(buf, 10, &state);
if (retval) if (retval)
return retval; return retval;
...@@ -578,18 +597,23 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev, ...@@ -578,18 +597,23 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev,
static ssize_t kone_sysfs_show_startup_profile(struct device *dev, static ssize_t kone_sysfs_show_startup_profile(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone =
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile); return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile);
} }
static ssize_t kone_sysfs_set_startup_profile(struct device *dev, static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
struct device_attribute *attr, char const *buf, size_t size) struct device_attribute *attr, char const *buf, size_t size)
{ {
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct kone_device *kone;
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); struct usb_device *usb_dev;
int retval; int retval;
unsigned long new_startup_profile; unsigned long new_startup_profile;
dev = dev->parent->parent;
kone = hid_get_drvdata(dev_get_drvdata(dev));
usb_dev = interface_to_usbdev(to_usb_interface(dev));
retval = strict_strtoul(buf, 10, &new_startup_profile); retval = strict_strtoul(buf, 10, &new_startup_profile);
if (retval) if (retval)
return retval; return retval;
...@@ -616,160 +640,87 @@ static ssize_t kone_sysfs_set_startup_profile(struct device *dev, ...@@ -616,160 +640,87 @@ static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
return size; return size;
} }
/* static struct device_attribute kone_attributes[] = {
* Read actual dpi settings. /*
* Returns raw value for further processing. Refer to enum kone_polling_rates to * Read actual dpi settings.
* get real value. * Returns raw value for further processing. Refer to enum
*/ * kone_polling_rates to get real value.
static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL); */
__ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL),
static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL); __ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL),
/*
* The mouse can be equipped with one of four supplied weights from 5 to 20
* grams which are recognized and its value can be read out.
* This returns the raw value reported by the mouse for easy evaluation by
* software. Refer to enum kone_weights to get corresponding real weight.
*/
static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL);
/*
* Prints firmware version stored in mouse as integer.
* The raw value reported by the mouse is returned for easy evaluation, to get
* the real version number the decimal point has to be shifted 2 positions to
* the left. E.g. a value of 138 means 1.38.
*/
static DEVICE_ATTR(firmware_version, 0440,
kone_sysfs_show_firmware_version, NULL);
/*
* Prints state of Tracking Control Unit as number where 0 = off and 1 = on
* Writing 0 deactivates tcu and writing 1 calibrates and activates the tcu
*/
static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu);
/* Prints and takes the number of the profile the mouse starts with */
static DEVICE_ATTR(startup_profile, 0660,
kone_sysfs_show_startup_profile,
kone_sysfs_set_startup_profile);
static struct attribute *kone_attributes[] = {
&dev_attr_actual_dpi.attr,
&dev_attr_actual_profile.attr,
&dev_attr_weight.attr,
&dev_attr_firmware_version.attr,
&dev_attr_tcu.attr,
&dev_attr_startup_profile.attr,
NULL
};
static struct attribute_group kone_attribute_group = {
.attrs = kone_attributes
};
static struct bin_attribute kone_settings_attr = {
.attr = { .name = "settings", .mode = 0660 },
.size = sizeof(struct kone_settings),
.read = kone_sysfs_read_settings,
.write = kone_sysfs_write_settings
};
static struct bin_attribute kone_profile1_attr = { /*
.attr = { .name = "profile1", .mode = 0660 }, * The mouse can be equipped with one of four supplied weights from 5
.size = sizeof(struct kone_profile), * to 20 grams which are recognized and its value can be read out.
.read = kone_sysfs_read_profile1, * This returns the raw value reported by the mouse for easy evaluation
.write = kone_sysfs_write_profile1 * by software. Refer to enum kone_weights to get corresponding real
}; * weight.
*/
__ATTR(weight, 0440, kone_sysfs_show_weight, NULL),
static struct bin_attribute kone_profile2_attr = { /*
.attr = { .name = "profile2", .mode = 0660 }, * Prints firmware version stored in mouse as integer.
.size = sizeof(struct kone_profile), * The raw value reported by the mouse is returned for easy evaluation,
.read = kone_sysfs_read_profile2, * to get the real version number the decimal point has to be shifted 2
.write = kone_sysfs_write_profile2 * positions to the left. E.g. a value of 138 means 1.38.
}; */
__ATTR(firmware_version, 0440,
kone_sysfs_show_firmware_version, NULL),
static struct bin_attribute kone_profile3_attr = { /*
.attr = { .name = "profile3", .mode = 0660 }, * Prints state of Tracking Control Unit as number where 0 = off and
.size = sizeof(struct kone_profile), * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and
.read = kone_sysfs_read_profile3, * activates the tcu
.write = kone_sysfs_write_profile3 */
}; __ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu),
static struct bin_attribute kone_profile4_attr = { /* Prints and takes the number of the profile the mouse starts with */
.attr = { .name = "profile4", .mode = 0660 }, __ATTR(startup_profile, 0660,
.size = sizeof(struct kone_profile), kone_sysfs_show_startup_profile,
.read = kone_sysfs_read_profile4, kone_sysfs_set_startup_profile),
.write = kone_sysfs_write_profile4 __ATTR_NULL
}; };
static struct bin_attribute kone_profile5_attr = { static struct bin_attribute kone_bin_attributes[] = {
.attr = { .name = "profile5", .mode = 0660 }, {
.size = sizeof(struct kone_profile), .attr = { .name = "settings", .mode = 0660 },
.read = kone_sysfs_read_profile5, .size = sizeof(struct kone_settings),
.write = kone_sysfs_write_profile5 .read = kone_sysfs_read_settings,
.write = kone_sysfs_write_settings
},
{
.attr = { .name = "profile1", .mode = 0660 },
.size = sizeof(struct kone_profile),
.read = kone_sysfs_read_profile1,
.write = kone_sysfs_write_profile1
},
{
.attr = { .name = "profile2", .mode = 0660 },
.size = sizeof(struct kone_profile),
.read = kone_sysfs_read_profile2,
.write = kone_sysfs_write_profile2
},
{
.attr = { .name = "profile3", .mode = 0660 },
.size = sizeof(struct kone_profile),
.read = kone_sysfs_read_profile3,
.write = kone_sysfs_write_profile3
},
{
.attr = { .name = "profile4", .mode = 0660 },
.size = sizeof(struct kone_profile),
.read = kone_sysfs_read_profile4,
.write = kone_sysfs_write_profile4
},
{
.attr = { .name = "profile5", .mode = 0660 },
.size = sizeof(struct kone_profile),
.read = kone_sysfs_read_profile5,
.write = kone_sysfs_write_profile5
},
__ATTR_NULL
}; };
static int kone_create_sysfs_attributes(struct usb_interface *intf)
{
int retval;
retval = sysfs_create_group(&intf->dev.kobj, &kone_attribute_group);
if (retval)
goto exit_1;
retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_settings_attr);
if (retval)
goto exit_2;
retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile1_attr);
if (retval)
goto exit_3;
retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile2_attr);
if (retval)
goto exit_4;
retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile3_attr);
if (retval)
goto exit_5;
retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile4_attr);
if (retval)
goto exit_6;
retval = sysfs_create_bin_file(&intf->dev.kobj, &kone_profile5_attr);
if (retval)
goto exit_7;
return 0;
exit_7:
sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile4_attr);
exit_6:
sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile3_attr);
exit_5:
sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile2_attr);
exit_4:
sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile1_attr);
exit_3:
sysfs_remove_bin_file(&intf->dev.kobj, &kone_settings_attr);
exit_2:
sysfs_remove_group(&intf->dev.kobj, &kone_attribute_group);
exit_1:
return retval;
}
static void kone_remove_sysfs_attributes(struct usb_interface *intf)
{
sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile5_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile4_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile3_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile2_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &kone_profile1_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &kone_settings_attr);
sysfs_remove_group(&intf->dev.kobj, &kone_attribute_group);
}
static int kone_init_kone_device_struct(struct usb_device *usb_dev, static int kone_init_kone_device_struct(struct usb_device *usb_dev,
struct kone_device *kone) struct kone_device *kone)
{ {
...@@ -828,7 +779,7 @@ static int kone_init_specials(struct hid_device *hdev) ...@@ -828,7 +779,7 @@ static int kone_init_specials(struct hid_device *hdev)
goto exit_free; goto exit_free;
} }
retval = roccat_connect(hdev); retval = roccat_connect(kone_class, hdev);
if (retval < 0) { if (retval < 0) {
hid_err(hdev, "couldn't init char dev\n"); hid_err(hdev, "couldn't init char dev\n");
/* be tolerant about not getting chrdev */ /* be tolerant about not getting chrdev */
...@@ -836,12 +787,6 @@ static int kone_init_specials(struct hid_device *hdev) ...@@ -836,12 +787,6 @@ static int kone_init_specials(struct hid_device *hdev)
kone->roccat_claimed = 1; kone->roccat_claimed = 1;
kone->chrdev_minor = retval; kone->chrdev_minor = retval;
} }
retval = kone_create_sysfs_attributes(intf);
if (retval) {
hid_err(hdev, "cannot create sysfs files\n");
goto exit_free;
}
} else { } else {
hid_set_drvdata(hdev, NULL); hid_set_drvdata(hdev, NULL);
} }
...@@ -852,7 +797,6 @@ static int kone_init_specials(struct hid_device *hdev) ...@@ -852,7 +797,6 @@ static int kone_init_specials(struct hid_device *hdev)
return retval; return retval;
} }
static void kone_remove_specials(struct hid_device *hdev) static void kone_remove_specials(struct hid_device *hdev)
{ {
struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
...@@ -860,7 +804,6 @@ static void kone_remove_specials(struct hid_device *hdev) ...@@ -860,7 +804,6 @@ static void kone_remove_specials(struct hid_device *hdev)
if (intf->cur_altsetting->desc.bInterfaceProtocol if (intf->cur_altsetting->desc.bInterfaceProtocol
== USB_INTERFACE_PROTOCOL_MOUSE) { == USB_INTERFACE_PROTOCOL_MOUSE) {
kone_remove_sysfs_attributes(intf);
kone = hid_get_drvdata(hdev); kone = hid_get_drvdata(hdev);
if (kone->roccat_claimed) if (kone->roccat_claimed)
roccat_disconnect(kone->chrdev_minor); roccat_disconnect(kone->chrdev_minor);
...@@ -1004,11 +947,24 @@ static struct hid_driver kone_driver = { ...@@ -1004,11 +947,24 @@ static struct hid_driver kone_driver = {
static int __init kone_init(void) static int __init kone_init(void)
{ {
return hid_register_driver(&kone_driver); int retval;
/* class name has to be same as driver name */
kone_class = class_create(THIS_MODULE, "kone");
if (IS_ERR(kone_class))
return PTR_ERR(kone_class);
kone_class->dev_attrs = kone_attributes;
kone_class->dev_bin_attrs = kone_bin_attributes;
retval = hid_register_driver(&kone_driver);
if (retval)
class_destroy(kone_class);
return retval;
} }
static void __exit kone_exit(void) static void __exit kone_exit(void)
{ {
class_destroy(kone_class);
hid_unregister_driver(&kone_driver); hid_unregister_driver(&kone_driver);
} }
......
...@@ -27,6 +27,9 @@ ...@@ -27,6 +27,9 @@
#include "hid-roccat.h" #include "hid-roccat.h"
#include "hid-roccat-pyra.h" #include "hid-roccat-pyra.h"
/* pyra_class is used for creating sysfs attributes via roccat char device */
static struct class *pyra_class;
static void profile_activated(struct pyra_device *pyra, static void profile_activated(struct pyra_device *pyra,
unsigned int new_profile) unsigned int new_profile)
{ {
...@@ -222,7 +225,8 @@ static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, ...@@ -222,7 +225,8 @@ static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf, struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count, int number) loff_t off, size_t count, int number)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev =
container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
if (off >= sizeof(struct pyra_profile_settings)) if (off >= sizeof(struct pyra_profile_settings))
...@@ -283,7 +287,8 @@ static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, ...@@ -283,7 +287,8 @@ static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf, struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count, int number) loff_t off, size_t count, int number)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev =
container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
if (off >= sizeof(struct pyra_profile_buttons)) if (off >= sizeof(struct pyra_profile_buttons))
...@@ -344,7 +349,8 @@ static ssize_t pyra_sysfs_write_profile_settings(struct file *fp, ...@@ -344,7 +349,8 @@ static ssize_t pyra_sysfs_write_profile_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf, struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count) loff_t off, size_t count)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev =
container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
int retval = 0; int retval = 0;
...@@ -380,7 +386,8 @@ static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp, ...@@ -380,7 +386,8 @@ static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf, struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count) loff_t off, size_t count)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev =
container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
int retval = 0; int retval = 0;
...@@ -416,7 +423,8 @@ static ssize_t pyra_sysfs_read_settings(struct file *fp, ...@@ -416,7 +423,8 @@ static ssize_t pyra_sysfs_read_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf, struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count) loff_t off, size_t count)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev =
container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
if (off >= sizeof(struct pyra_settings)) if (off >= sizeof(struct pyra_settings))
...@@ -436,7 +444,8 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, ...@@ -436,7 +444,8 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,
struct kobject *kobj, struct bin_attribute *attr, char *buf, struct kobject *kobj, struct bin_attribute *attr, char *buf,
loff_t off, size_t count) loff_t off, size_t count)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev =
container_of(kobj, struct device, kobj)->parent->parent;
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
int retval = 0; int retval = 0;
...@@ -468,255 +477,115 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, ...@@ -468,255 +477,115 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,
static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev, static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct pyra_device *pyra =
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi); return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
} }
static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct pyra_device *pyra =
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile); return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile);
} }
static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct pyra_device *pyra =
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version); return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version);
} }
static ssize_t pyra_sysfs_show_startup_profile(struct device *dev, static ssize_t pyra_sysfs_show_startup_profile(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct pyra_device *pyra =
hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile); return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile);
} }
static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL); static struct device_attribute pyra_attributes[] = {
__ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL),
static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL); __ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL),
__ATTR(firmware_version, 0440,
static DEVICE_ATTR(firmware_version, 0440, pyra_sysfs_show_firmware_version, NULL),
pyra_sysfs_show_firmware_version, NULL); __ATTR(startup_profile, 0440,
pyra_sysfs_show_startup_profile, NULL),
static DEVICE_ATTR(startup_profile, 0440, __ATTR_NULL
pyra_sysfs_show_startup_profile, NULL);
static struct attribute *pyra_attributes[] = {
&dev_attr_actual_cpi.attr,
&dev_attr_actual_profile.attr,
&dev_attr_firmware_version.attr,
&dev_attr_startup_profile.attr,
NULL
};
static struct attribute_group pyra_attribute_group = {
.attrs = pyra_attributes
}; };
static struct bin_attribute pyra_profile_settings_attr = { static struct bin_attribute pyra_bin_attributes[] = {
{
.attr = { .name = "profile_settings", .mode = 0220 }, .attr = { .name = "profile_settings", .mode = 0220 },
.size = sizeof(struct pyra_profile_settings), .size = sizeof(struct pyra_profile_settings),
.write = pyra_sysfs_write_profile_settings .write = pyra_sysfs_write_profile_settings
}; },
{
static struct bin_attribute pyra_profile1_settings_attr = {
.attr = { .name = "profile1_settings", .mode = 0440 }, .attr = { .name = "profile1_settings", .mode = 0440 },
.size = sizeof(struct pyra_profile_settings), .size = sizeof(struct pyra_profile_settings),
.read = pyra_sysfs_read_profile1_settings .read = pyra_sysfs_read_profile1_settings
}; },
{
static struct bin_attribute pyra_profile2_settings_attr = {
.attr = { .name = "profile2_settings", .mode = 0440 }, .attr = { .name = "profile2_settings", .mode = 0440 },
.size = sizeof(struct pyra_profile_settings), .size = sizeof(struct pyra_profile_settings),
.read = pyra_sysfs_read_profile2_settings .read = pyra_sysfs_read_profile2_settings
}; },
{
static struct bin_attribute pyra_profile3_settings_attr = {
.attr = { .name = "profile3_settings", .mode = 0440 }, .attr = { .name = "profile3_settings", .mode = 0440 },
.size = sizeof(struct pyra_profile_settings), .size = sizeof(struct pyra_profile_settings),
.read = pyra_sysfs_read_profile3_settings .read = pyra_sysfs_read_profile3_settings
}; },
{
static struct bin_attribute pyra_profile4_settings_attr = {
.attr = { .name = "profile4_settings", .mode = 0440 }, .attr = { .name = "profile4_settings", .mode = 0440 },
.size = sizeof(struct pyra_profile_settings), .size = sizeof(struct pyra_profile_settings),
.read = pyra_sysfs_read_profile4_settings .read = pyra_sysfs_read_profile4_settings
}; },
{
static struct bin_attribute pyra_profile5_settings_attr = {
.attr = { .name = "profile5_settings", .mode = 0440 }, .attr = { .name = "profile5_settings", .mode = 0440 },
.size = sizeof(struct pyra_profile_settings), .size = sizeof(struct pyra_profile_settings),
.read = pyra_sysfs_read_profile5_settings .read = pyra_sysfs_read_profile5_settings
}; },
{
static struct bin_attribute pyra_profile_buttons_attr = {
.attr = { .name = "profile_buttons", .mode = 0220 }, .attr = { .name = "profile_buttons", .mode = 0220 },
.size = sizeof(struct pyra_profile_buttons), .size = sizeof(struct pyra_profile_buttons),
.write = pyra_sysfs_write_profile_buttons .write = pyra_sysfs_write_profile_buttons
}; },
{
static struct bin_attribute pyra_profile1_buttons_attr = {
.attr = { .name = "profile1_buttons", .mode = 0440 }, .attr = { .name = "profile1_buttons", .mode = 0440 },
.size = sizeof(struct pyra_profile_buttons), .size = sizeof(struct pyra_profile_buttons),
.read = pyra_sysfs_read_profile1_buttons .read = pyra_sysfs_read_profile1_buttons
}; },
{
static struct bin_attribute pyra_profile2_buttons_attr = {
.attr = { .name = "profile2_buttons", .mode = 0440 }, .attr = { .name = "profile2_buttons", .mode = 0440 },
.size = sizeof(struct pyra_profile_buttons), .size = sizeof(struct pyra_profile_buttons),
.read = pyra_sysfs_read_profile2_buttons .read = pyra_sysfs_read_profile2_buttons
}; },
{
static struct bin_attribute pyra_profile3_buttons_attr = {
.attr = { .name = "profile3_buttons", .mode = 0440 }, .attr = { .name = "profile3_buttons", .mode = 0440 },
.size = sizeof(struct pyra_profile_buttons), .size = sizeof(struct pyra_profile_buttons),
.read = pyra_sysfs_read_profile3_buttons .read = pyra_sysfs_read_profile3_buttons
}; },
{
static struct bin_attribute pyra_profile4_buttons_attr = {
.attr = { .name = "profile4_buttons", .mode = 0440 }, .attr = { .name = "profile4_buttons", .mode = 0440 },
.size = sizeof(struct pyra_profile_buttons), .size = sizeof(struct pyra_profile_buttons),
.read = pyra_sysfs_read_profile4_buttons .read = pyra_sysfs_read_profile4_buttons
}; },
{
static struct bin_attribute pyra_profile5_buttons_attr = {
.attr = { .name = "profile5_buttons", .mode = 0440 }, .attr = { .name = "profile5_buttons", .mode = 0440 },
.size = sizeof(struct pyra_profile_buttons), .size = sizeof(struct pyra_profile_buttons),
.read = pyra_sysfs_read_profile5_buttons .read = pyra_sysfs_read_profile5_buttons
}; },
{
static struct bin_attribute pyra_settings_attr = {
.attr = { .name = "settings", .mode = 0660 }, .attr = { .name = "settings", .mode = 0660 },
.size = sizeof(struct pyra_settings), .size = sizeof(struct pyra_settings),
.read = pyra_sysfs_read_settings, .read = pyra_sysfs_read_settings,
.write = pyra_sysfs_write_settings .write = pyra_sysfs_write_settings
},
__ATTR_NULL
}; };
static int pyra_create_sysfs_attributes(struct usb_interface *intf)
{
int retval;
retval = sysfs_create_group(&intf->dev.kobj, &pyra_attribute_group);
if (retval)
goto exit_1;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile_settings_attr);
if (retval)
goto exit_2;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile1_settings_attr);
if (retval)
goto exit_3;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile2_settings_attr);
if (retval)
goto exit_4;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile3_settings_attr);
if (retval)
goto exit_5;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile4_settings_attr);
if (retval)
goto exit_6;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile5_settings_attr);
if (retval)
goto exit_7;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile_buttons_attr);
if (retval)
goto exit_8;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile1_buttons_attr);
if (retval)
goto exit_9;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile2_buttons_attr);
if (retval)
goto exit_10;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile3_buttons_attr);
if (retval)
goto exit_11;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile4_buttons_attr);
if (retval)
goto exit_12;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_profile5_buttons_attr);
if (retval)
goto exit_13;
retval = sysfs_create_bin_file(&intf->dev.kobj,
&pyra_settings_attr);
if (retval)
goto exit_14;
return 0;
exit_14:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
exit_13:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
exit_12:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
exit_11:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
exit_10:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
exit_9:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
exit_8:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
exit_7:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
exit_6:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
exit_5:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
exit_4:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
exit_3:
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
exit_2:
sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
exit_1:
return retval;
}
static void pyra_remove_sysfs_attributes(struct usb_interface *intf)
{
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_settings_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
}
static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
struct pyra_device *pyra) struct pyra_device *pyra)
{ {
...@@ -780,19 +649,13 @@ static int pyra_init_specials(struct hid_device *hdev) ...@@ -780,19 +649,13 @@ static int pyra_init_specials(struct hid_device *hdev)
goto exit_free; goto exit_free;
} }
retval = roccat_connect(hdev); retval = roccat_connect(pyra_class, hdev);
if (retval < 0) { if (retval < 0) {
hid_err(hdev, "couldn't init char dev\n"); hid_err(hdev, "couldn't init char dev\n");
} else { } else {
pyra->chrdev_minor = retval; pyra->chrdev_minor = retval;
pyra->roccat_claimed = 1; pyra->roccat_claimed = 1;
} }
retval = pyra_create_sysfs_attributes(intf);
if (retval) {
hid_err(hdev, "cannot create sysfs files\n");
goto exit_free;
}
} else { } else {
hid_set_drvdata(hdev, NULL); hid_set_drvdata(hdev, NULL);
} }
...@@ -810,7 +673,6 @@ static void pyra_remove_specials(struct hid_device *hdev) ...@@ -810,7 +673,6 @@ static void pyra_remove_specials(struct hid_device *hdev)
if (intf->cur_altsetting->desc.bInterfaceProtocol if (intf->cur_altsetting->desc.bInterfaceProtocol
== USB_INTERFACE_PROTOCOL_MOUSE) { == USB_INTERFACE_PROTOCOL_MOUSE) {
pyra_remove_sysfs_attributes(intf);
pyra = hid_get_drvdata(hdev); pyra = hid_get_drvdata(hdev);
if (pyra->roccat_claimed) if (pyra->roccat_claimed)
roccat_disconnect(pyra->chrdev_minor); roccat_disconnect(pyra->chrdev_minor);
...@@ -950,11 +812,24 @@ static struct hid_driver pyra_driver = { ...@@ -950,11 +812,24 @@ static struct hid_driver pyra_driver = {
static int __init pyra_init(void) static int __init pyra_init(void)
{ {
return hid_register_driver(&pyra_driver); int retval;
/* class name has to be same as driver name */
pyra_class = class_create(THIS_MODULE, "pyra");
if (IS_ERR(pyra_class))
return PTR_ERR(pyra_class);
pyra_class->dev_attrs = pyra_attributes;
pyra_class->dev_bin_attrs = pyra_bin_attributes;
retval = hid_register_driver(&pyra_driver);
if (retval)
class_destroy(pyra_class);
return retval;
} }
static void __exit pyra_exit(void) static void __exit pyra_exit(void)
{ {
class_destroy(pyra_class);
hid_unregister_driver(&pyra_driver); hid_unregister_driver(&pyra_driver);
} }
......
...@@ -67,7 +67,6 @@ struct roccat_reader { ...@@ -67,7 +67,6 @@ struct roccat_reader {
}; };
static int roccat_major; static int roccat_major;
static struct class *roccat_class;
static struct cdev roccat_cdev; static struct cdev roccat_cdev;
static struct roccat_device *devices[ROCCAT_MAX_DEVICES]; static struct roccat_device *devices[ROCCAT_MAX_DEVICES];
...@@ -289,12 +288,14 @@ EXPORT_SYMBOL_GPL(roccat_report_event); ...@@ -289,12 +288,14 @@ EXPORT_SYMBOL_GPL(roccat_report_event);
/* /*
* roccat_connect() - create a char device for special event output * roccat_connect() - create a char device for special event output
* @class: the class thats used to create the device. Meant to hold device
* specific sysfs attributes.
* @hid: the hid device the char device should be connected to. * @hid: the hid device the char device should be connected to.
* *
* Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on
* success, a negative error code on failure. * success, a negative error code on failure.
*/ */
int roccat_connect(struct hid_device *hid) int roccat_connect(struct class *klass, struct hid_device *hid)
{ {
unsigned int minor; unsigned int minor;
struct roccat_device *device; struct roccat_device *device;
...@@ -320,7 +321,7 @@ int roccat_connect(struct hid_device *hid) ...@@ -320,7 +321,7 @@ int roccat_connect(struct hid_device *hid)
return -EINVAL; return -EINVAL;
} }
device->dev = device_create(roccat_class, &hid->dev, device->dev = device_create(klass, &hid->dev,
MKDEV(roccat_major, minor), NULL, MKDEV(roccat_major, minor), NULL,
"%s%s%d", "roccat", hid->driver->name, minor); "%s%s%d", "roccat", hid->driver->name, minor);
...@@ -361,7 +362,7 @@ void roccat_disconnect(int minor) ...@@ -361,7 +362,7 @@ void roccat_disconnect(int minor)
device->exist = 0; /* TODO exist maybe not needed */ device->exist = 0; /* TODO exist maybe not needed */
device_destroy(roccat_class, MKDEV(roccat_major, minor)); device_destroy(device->dev->class, MKDEV(roccat_major, minor));
if (device->open) { if (device->open) {
hid_hw_close(device->hid); hid_hw_close(device->hid);
...@@ -396,13 +397,6 @@ static int __init roccat_init(void) ...@@ -396,13 +397,6 @@ static int __init roccat_init(void)
return retval; return retval;
} }
roccat_class = class_create(THIS_MODULE, "roccat");
if (IS_ERR(roccat_class)) {
retval = PTR_ERR(roccat_class);
unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES);
return retval;
}
cdev_init(&roccat_cdev, &roccat_ops); cdev_init(&roccat_cdev, &roccat_ops);
cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES); cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES);
...@@ -414,7 +408,6 @@ static void __exit roccat_exit(void) ...@@ -414,7 +408,6 @@ static void __exit roccat_exit(void)
dev_t dev_id = MKDEV(roccat_major, 0); dev_t dev_id = MKDEV(roccat_major, 0);
cdev_del(&roccat_cdev); cdev_del(&roccat_cdev);
class_destroy(roccat_class);
unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES); unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES);
} }
......
...@@ -16,11 +16,12 @@ ...@@ -16,11 +16,12 @@
#include <linux/types.h> #include <linux/types.h>
#if defined(CONFIG_HID_ROCCAT) || defined(CONFIG_HID_ROCCAT_MODULE) #if defined(CONFIG_HID_ROCCAT) || defined(CONFIG_HID_ROCCAT_MODULE)
int roccat_connect(struct hid_device *hid); int roccat_connect(struct class *klass, struct hid_device *hid);
void roccat_disconnect(int minor); void roccat_disconnect(int minor);
int roccat_report_event(int minor, u8 const *data, int len); int roccat_report_event(int minor, u8 const *data, int len);
#else #else
static inline int roccat_connect(struct hid_device *hid) { return -1; } static inline int roccat_connect(struct class *klass,
struct hid_device *hid) { return -1; }
static inline void roccat_disconnect(int minor) {} static inline void roccat_disconnect(int minor) {}
static inline int roccat_report_event(int minor, u8 const *data, int len) static inline int roccat_report_event(int minor, u8 const *data, int len)
{ {
......
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