aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r--drivers/hid/hid-core.c120
1 files changed, 109 insertions, 11 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 40df3e1b4bd..5d7640e49dc 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1256,19 +1256,16 @@ static const struct hid_device_id hid_blacklist[] = {
1256 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, 1256 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1257 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, 1257 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
1258 { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, 1258 { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
1259 { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) },
1260 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, 1259 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
1261 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, 1260 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
1262 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, 1261 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
1263 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, 1262 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
1264 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, 1263 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
1265 { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658) },
1266 { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) },
1267 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, 1264 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
1268 { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) },
1269 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, 1265 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
1270 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, 1266 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
1271 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, 1267 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
1268 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
1272 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, 1269 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
1273 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, 1270 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
1274 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, 1271 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
@@ -1279,7 +1276,6 @@ static const struct hid_device_id hid_blacklist[] = {
1279 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, 1276 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
1280 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, 1277 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) },
1281 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, 1278 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) },
1282 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD) },
1283 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, 1279 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) },
1284 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, 1280 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
1285 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, 1281 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
@@ -1297,23 +1293,105 @@ static const struct hid_device_id hid_blacklist[] = {
1297 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, 1293 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
1298 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, 1294 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
1299 { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, 1295 { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
1296 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
1300 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, 1297 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
1301 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1298 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1302 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1299 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1303 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, 1300 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
1304 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, 1301 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
1302 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
1305 1303
1306 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, 1304 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
1307 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, 1305 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
1308 { } 1306 { }
1309}; 1307};
1310 1308
1309struct hid_dynid {
1310 struct list_head list;
1311 struct hid_device_id id;
1312};
1313
1314/**
1315 * store_new_id - add a new HID device ID to this driver and re-probe devices
1316 * @driver: target device driver
1317 * @buf: buffer for scanning device ID data
1318 * @count: input size
1319 *
1320 * Adds a new dynamic hid device ID to this driver,
1321 * and causes the driver to probe for all devices again.
1322 */
1323static ssize_t store_new_id(struct device_driver *drv, const char *buf,
1324 size_t count)
1325{
1326 struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver);
1327 struct hid_dynid *dynid;
1328 __u32 bus, vendor, product;
1329 unsigned long driver_data = 0;
1330 int ret;
1331
1332 ret = sscanf(buf, "%x %x %x %lx",
1333 &bus, &vendor, &product, &driver_data);
1334 if (ret < 3)
1335 return -EINVAL;
1336
1337 dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
1338 if (!dynid)
1339 return -ENOMEM;
1340
1341 dynid->id.bus = bus;
1342 dynid->id.vendor = vendor;
1343 dynid->id.product = product;
1344 dynid->id.driver_data = driver_data;
1345
1346 spin_lock(&hdrv->dyn_lock);
1347 list_add_tail(&dynid->list, &hdrv->dyn_list);
1348 spin_unlock(&hdrv->dyn_lock);
1349
1350 ret = 0;
1351 if (get_driver(&hdrv->driver)) {
1352 ret = driver_attach(&hdrv->driver);
1353 put_driver(&hdrv->driver);
1354 }
1355
1356 return ret ? : count;
1357}
1358static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
1359
1360static void hid_free_dynids(struct hid_driver *hdrv)
1361{
1362 struct hid_dynid *dynid, *n;
1363
1364 spin_lock(&hdrv->dyn_lock);
1365 list_for_each_entry_safe(dynid, n, &hdrv->dyn_list, list) {
1366 list_del(&dynid->list);
1367 kfree(dynid);
1368 }
1369 spin_unlock(&hdrv->dyn_lock);
1370}
1371
1372static const struct hid_device_id *hid_match_device(struct hid_device *hdev,
1373 struct hid_driver *hdrv)
1374{
1375 struct hid_dynid *dynid;
1376
1377 spin_lock(&hdrv->dyn_lock);
1378 list_for_each_entry(dynid, &hdrv->dyn_list, list) {
1379 if (hid_match_one_id(hdev, &dynid->id)) {
1380 spin_unlock(&hdrv->dyn_lock);
1381 return &dynid->id;
1382 }
1383 }
1384 spin_unlock(&hdrv->dyn_lock);
1385
1386 return hid_match_id(hdev, hdrv->id_table);
1387}
1388
1311static int hid_bus_match(struct device *dev, struct device_driver *drv) 1389static int hid_bus_match(struct device *dev, struct device_driver *drv)
1312{ 1390{
1313 struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); 1391 struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver);
1314 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1392 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1315 1393
1316 if (!hid_match_id(hdev, hdrv->id_table)) 1394 if (!hid_match_device(hdev, hdrv))
1317 return 0; 1395 return 0;
1318 1396
1319 /* generic wants all non-blacklisted */ 1397 /* generic wants all non-blacklisted */
@@ -1332,7 +1410,7 @@ static int hid_device_probe(struct device *dev)
1332 int ret = 0; 1410 int ret = 0;
1333 1411
1334 if (!hdev->driver) { 1412 if (!hdev->driver) {
1335 id = hid_match_id(hdev, hdrv->id_table); 1413 id = hid_match_device(hdev, hdrv);
1336 if (id == NULL) 1414 if (id == NULL)
1337 return -ENODEV; 1415 return -ENODEV;
1338 1416
@@ -1420,6 +1498,7 @@ static const struct hid_device_id hid_ignore_list[] = {
1420 { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) }, 1498 { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) },
1421 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) }, 1499 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) },
1422 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) }, 1500 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) },
1501 { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) },
1423 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, 1502 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
1424 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, 1503 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
1425 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, 1504 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
@@ -1577,6 +1656,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
1577 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, 1656 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
1578 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, 1657 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
1579 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, 1658 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
1659 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
1660 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
1661 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
1580 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, 1662 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1581 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, 1663 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
1582 { } 1664 { }
@@ -1618,9 +1700,10 @@ int hid_add_device(struct hid_device *hdev)
1618 if (hid_ignore(hdev)) 1700 if (hid_ignore(hdev))
1619 return -ENODEV; 1701 return -ENODEV;
1620 1702
1621 /* XXX hack, any other cleaner solution < 20 bus_id bytes? */ 1703 /* XXX hack, any other cleaner solution after the driver core
1622 sprintf(hdev->dev.bus_id, "%04X:%04X:%04X.%04X", hdev->bus, 1704 * is converted to allow more than 20 bytes as the device name? */
1623 hdev->vendor, hdev->product, atomic_inc_return(&id)); 1705 dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
1706 hdev->vendor, hdev->product, atomic_inc_return(&id));
1624 1707
1625 ret = device_add(&hdev->dev); 1708 ret = device_add(&hdev->dev);
1626 if (!ret) 1709 if (!ret)
@@ -1695,18 +1778,33 @@ EXPORT_SYMBOL_GPL(hid_destroy_device);
1695int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, 1778int __hid_register_driver(struct hid_driver *hdrv, struct module *owner,
1696 const char *mod_name) 1779 const char *mod_name)
1697{ 1780{
1781 int ret;
1782
1698 hdrv->driver.name = hdrv->name; 1783 hdrv->driver.name = hdrv->name;
1699 hdrv->driver.bus = &hid_bus_type; 1784 hdrv->driver.bus = &hid_bus_type;
1700 hdrv->driver.owner = owner; 1785 hdrv->driver.owner = owner;
1701 hdrv->driver.mod_name = mod_name; 1786 hdrv->driver.mod_name = mod_name;
1702 1787
1703 return driver_register(&hdrv->driver); 1788 INIT_LIST_HEAD(&hdrv->dyn_list);
1789 spin_lock_init(&hdrv->dyn_lock);
1790
1791 ret = driver_register(&hdrv->driver);
1792 if (ret)
1793 return ret;
1794
1795 ret = driver_create_file(&hdrv->driver, &driver_attr_new_id);
1796 if (ret)
1797 driver_unregister(&hdrv->driver);
1798
1799 return ret;
1704} 1800}
1705EXPORT_SYMBOL_GPL(__hid_register_driver); 1801EXPORT_SYMBOL_GPL(__hid_register_driver);
1706 1802
1707void hid_unregister_driver(struct hid_driver *hdrv) 1803void hid_unregister_driver(struct hid_driver *hdrv)
1708{ 1804{
1805 driver_remove_file(&hdrv->driver, &driver_attr_new_id);
1709 driver_unregister(&hdrv->driver); 1806 driver_unregister(&hdrv->driver);
1807 hid_free_dynids(hdrv);
1710} 1808}
1711EXPORT_SYMBOL_GPL(hid_unregister_driver); 1809EXPORT_SYMBOL_GPL(hid_unregister_driver);
1712 1810