return error;
}
-struct wacom_usbdev_data {
+struct wacom_hdev_data {
struct list_head list;
struct kref kref;
- struct usb_device *dev;
+ struct hid_device *dev;
struct wacom_shared shared;
};
static LIST_HEAD(wacom_udev_list);
static DEFINE_MUTEX(wacom_udev_list_lock);
-static struct usb_device *wacom_get_sibling(struct usb_device *dev, int vendor, int product)
+static bool wacom_are_sibling(struct hid_device *hdev,
+ struct hid_device *sibling)
{
- int port1;
- struct usb_device *sibling;
-
- if (vendor == 0 && product == 0)
- return dev;
+ struct wacom *wacom = hid_get_drvdata(hdev);
+ struct wacom_features *features = &wacom->wacom_wac.features;
+ int vid = features->oVid;
+ int pid = features->oPid;
+ int n1,n2;
- if (dev->parent == NULL)
- return NULL;
+ if (vid == 0 && pid == 0) {
+ vid = hdev->vendor;
+ pid = hdev->product;
+ }
- usb_hub_for_each_child(dev->parent, port1, sibling) {
- struct usb_device_descriptor *d;
- if (sibling == NULL)
- continue;
+ if (vid != sibling->vendor || pid != sibling->product)
+ return false;
- d = &sibling->descriptor;
- if (d->idVendor == vendor && d->idProduct == product)
- return sibling;
- }
+ /* Compare the physical path. */
+ n1 = strrchr(hdev->phys, '.') - hdev->phys;
+ n2 = strrchr(sibling->phys, '.') - sibling->phys;
+ if (n1 != n2 || n1 <= 0 || n2 <= 0)
+ return false;
- return NULL;
+ return !strncmp(hdev->phys, sibling->phys, n1);
}
-static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev)
+static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev)
{
- struct wacom_usbdev_data *data;
+ struct wacom_hdev_data *data;
list_for_each_entry(data, &wacom_udev_list, list) {
- if (data->dev == dev) {
+ if (wacom_are_sibling(hdev, data->dev)) {
kref_get(&data->kref);
return data;
}
return NULL;
}
-static int wacom_add_shared_data(struct wacom_wac *wacom,
- struct usb_device *dev)
+static int wacom_add_shared_data(struct hid_device *hdev)
{
- struct wacom_usbdev_data *data;
+ struct wacom *wacom = hid_get_drvdata(hdev);
+ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+ struct wacom_hdev_data *data;
int retval = 0;
mutex_lock(&wacom_udev_list_lock);
- data = wacom_get_usbdev_data(dev);
+ data = wacom_get_hdev_data(hdev);
if (!data) {
- data = kzalloc(sizeof(struct wacom_usbdev_data), GFP_KERNEL);
+ data = kzalloc(sizeof(struct wacom_hdev_data), GFP_KERNEL);
if (!data) {
retval = -ENOMEM;
goto out;
}
kref_init(&data->kref);
- data->dev = dev;
+ data->dev = hdev;
list_add_tail(&data->list, &wacom_udev_list);
}
- wacom->shared = &data->shared;
+ wacom_wac->shared = &data->shared;
out:
mutex_unlock(&wacom_udev_list_lock);
static void wacom_release_shared_data(struct kref *kref)
{
- struct wacom_usbdev_data *data =
- container_of(kref, struct wacom_usbdev_data, kref);
+ struct wacom_hdev_data *data =
+ container_of(kref, struct wacom_hdev_data, kref);
mutex_lock(&wacom_udev_list_lock);
list_del(&data->list);
static void wacom_remove_shared_data(struct wacom_wac *wacom)
{
- struct wacom_usbdev_data *data;
+ struct wacom_hdev_data *data;
if (wacom->shared) {
- data = container_of(wacom->shared, struct wacom_usbdev_data, shared);
+ data = container_of(wacom->shared, struct wacom_hdev_data, shared);
kref_put(&data->kref, wacom_release_shared_data);
wacom->shared = NULL;
}
"%s Pad", features->name);
if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
- struct usb_device *other_dev;
-
/* Append the device type to the name */
if (features->device_type != BTN_TOOL_FINGER)
strlcat(wacom_wac->name, " Pen", WACOM_NAME_MAX);
else
strlcat(wacom_wac->name, " Pad", WACOM_NAME_MAX);
- other_dev = wacom_get_sibling(dev, features->oVid, features->oPid);
- if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL)
- other_dev = dev;
- error = wacom_add_shared_data(wacom_wac, other_dev);
+ error = wacom_add_shared_data(hdev);
if (error)
goto fail1;
}