From ce4804037961af1ba284260466f460c0d3e3c1e1 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Tue, 5 Jul 2016 13:47:33 -0400 Subject: [PATCH 2/2] hid: sony: Fix power supply creation when devices have the same BT address The Sony module uses the device's Bluetooth address as the unique identifier for the battery power supply name. The can cause name collisions when multiple USB-only devices masquerading as Sixaxis controllers are connected at the same time and all of the devices report the same dummy Bluetooth address. This patch attempts to resolve the name collisions by appending the unique device_id to the end of the name string if the initial power supply creation attempt returns an -EEXIST error. Other errors and instances of -EEXIST after the retry attempt are handled as before. Signed-off-by: Frank Praznik --- drivers/hid/hid-sony.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 4818ca2..c08c74e 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -2044,9 +2044,14 @@ static int sony_battery_get_property(struct power_supply *psy, static int sony_battery_probe(struct sony_sc *sc) { + static const char * const name_fmt[] = { + "sony_controller_battery_%pMR", + "sony_controller_battery_%pMR_%i" + }; struct power_supply_config psy_cfg = { .drv_data = sc, }; struct hid_device *hdev = sc->hdev; int ret; + int retry_count = 0; /* * Set the default battery level to 100% to avoid low battery warnings @@ -2059,9 +2064,11 @@ static int sony_battery_probe(struct sony_sc *sc) sc->battery_desc.get_property = sony_battery_get_property; sc->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; sc->battery_desc.use_for_apm = 0; + +try_again: sc->battery_desc.name = kasprintf(GFP_KERNEL, - "sony_controller_battery_%pMR", - sc->mac_address); + name_fmt[retry_count], + sc->mac_address, sc->device_id); if (!sc->battery_desc.name) return -ENOMEM; @@ -2069,8 +2076,19 @@ static int sony_battery_probe(struct sony_sc *sc) &psy_cfg); if (IS_ERR(sc->battery)) { ret = PTR_ERR(sc->battery); - hid_err(hdev, "Unable to register battery device\n"); - goto err_free; + + if (ret != -EEXIST || retry_count) { + hid_err(hdev, "Unable to register battery device\n"); + goto err_free; + } else { + /* + * Name collision, try again with a unique identifier + * appended to the name string. + */ + kfree(sc->battery_desc.name); + ++retry_count; + goto try_again; + } } power_supply_powers(sc->battery, &hdev->dev); -- 2.7.4