dock_notify.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2015-2023 Samsung Electronics Co. Ltd.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. */
  10. /* usb notify layer v4.0 */
  11. #define pr_fmt(fmt) "usb_notify: " fmt
  12. #include <linux/module.h>
  13. #include <linux/kernel.h>
  14. #include <linux/err.h>
  15. #include <linux/usb.h>
  16. #include <linux/notifier.h>
  17. #include <linux/version.h>
  18. #include <linux/usb_notify.h>
  19. #include <linux/usb/hcd.h>
  20. #define SMARTDOCK_INDEX 1
  21. #define MMDOCK_INDEX 2
  22. struct dev_table {
  23. struct usb_device_id dev;
  24. int index;
  25. };
  26. static struct dev_table enable_notify_hub_table[] = {
  27. { .dev = { USB_DEVICE(0x0424, 0x2514), },
  28. .index = SMARTDOCK_INDEX,
  29. }, /* SMART DOCK HUB 1 */
  30. { .dev = { USB_DEVICE(0x1a40, 0x0101), },
  31. .index = SMARTDOCK_INDEX,
  32. }, /* SMART DOCK HUB 2 */
  33. { .dev = { USB_DEVICE(0x0424, 0x9512), },
  34. .index = MMDOCK_INDEX,
  35. }, /* SMSC USB LAN HUB 9512 */
  36. {}
  37. };
  38. static struct dev_table essential_device_table[] = {
  39. { .dev = { USB_DEVICE(0x08bb, 0x2704), },
  40. .index = SMARTDOCK_INDEX,
  41. }, /* TI USB Audio DAC 1 */
  42. { .dev = { USB_DEVICE(0x08bb, 0x27c4), },
  43. .index = SMARTDOCK_INDEX,
  44. }, /* TI USB Audio DAC 2 */
  45. { .dev = { USB_DEVICE(0x0424, 0xec00), },
  46. .index = MMDOCK_INDEX,
  47. }, /* SMSC LAN Driver */
  48. {}
  49. };
  50. static struct dev_table unsupport_device_table[] = {
  51. { .dev = { USB_DEVICE(0x1a0a, 0x0201), },
  52. }, /* The device for usb certification */
  53. {}
  54. };
  55. static int check_essential_device(struct usb_device *dev, int index)
  56. {
  57. struct dev_table *id;
  58. int ret = 0;
  59. /* check VID, PID */
  60. for (id = essential_device_table; id->dev.match_flags; id++) {
  61. if ((id->dev.match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
  62. (id->dev.match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
  63. id->dev.idVendor == le16_to_cpu(dev->descriptor.idVendor) &&
  64. id->dev.idProduct == le16_to_cpu(dev->descriptor.idProduct) &&
  65. id->index == index) {
  66. ret = 1;
  67. break;
  68. }
  69. }
  70. return ret;
  71. }
  72. static int check_gamepad_device(struct usb_device *dev)
  73. {
  74. int ret = 0;
  75. unl_info("%s : product=%s\n", __func__, dev->product);
  76. if (!dev->product)
  77. return ret;
  78. if (!strncmp(dev->product, "Gamepad for SAMSUNG", 19))
  79. ret = 1;
  80. return ret;
  81. }
  82. static int check_lanhub_device(struct usb_device *dev)
  83. {
  84. int ret = 0;
  85. unl_info("%s : product=%s\n", __func__, dev->product);
  86. if (!dev->product)
  87. return ret;
  88. if (!strncmp(dev->product, "LAN9512", 8))
  89. ret = 1;
  90. return ret;
  91. }
  92. static int is_notify_hub(struct usb_device *dev)
  93. {
  94. struct dev_table *id;
  95. struct usb_device *hdev;
  96. int ret = 0;
  97. hdev = dev->parent;
  98. if (!hdev)
  99. goto skip;
  100. /* check VID, PID */
  101. for (id = enable_notify_hub_table; id->dev.match_flags; id++) {
  102. if ((id->dev.match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
  103. (id->dev.match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
  104. id->dev.idVendor == le16_to_cpu(hdev->descriptor.idVendor) &&
  105. id->dev.idProduct == le16_to_cpu(hdev->descriptor.idProduct)) {
  106. ret = (hdev->parent &&
  107. (hdev->parent == dev->bus->root_hub)) ? id->index : 0;
  108. break;
  109. }
  110. }
  111. skip:
  112. return ret;
  113. }
  114. static int call_battery_notify(struct usb_device *dev, bool on)
  115. {
  116. struct usb_device *hdev;
  117. struct usb_device *udev;
  118. struct otg_notify *o_notify = get_otg_notify();
  119. int index = 0;
  120. int count = 0;
  121. int port;
  122. index = is_notify_hub(dev);
  123. if (!index)
  124. goto skip;
  125. if (!check_essential_device(dev, index))
  126. goto skip;
  127. hdev = dev->parent;
  128. if (!hdev)
  129. goto skip;
  130. usb_hub_for_each_child(hdev, port, udev) {
  131. if (check_essential_device(udev, index)) {
  132. if (!on && (udev == dev))
  133. continue;
  134. else
  135. count++;
  136. }
  137. }
  138. unl_info("%s : VID : 0x%x, PID : 0x%x, on=%d, count=%d\n", __func__,
  139. dev->descriptor.idVendor, dev->descriptor.idProduct,
  140. on, count);
  141. if (on) {
  142. if (count == 1) {
  143. if (index == SMARTDOCK_INDEX)
  144. send_otg_notify(o_notify,
  145. NOTIFY_EVENT_SMTD_EXT_CURRENT, 1);
  146. else if (index == MMDOCK_INDEX)
  147. send_otg_notify(o_notify,
  148. NOTIFY_EVENT_MMD_EXT_CURRENT, 1);
  149. }
  150. } else {
  151. if (!count) {
  152. if (index == SMARTDOCK_INDEX)
  153. send_otg_notify(o_notify,
  154. NOTIFY_EVENT_SMTD_EXT_CURRENT, 0);
  155. else if (index == MMDOCK_INDEX)
  156. send_otg_notify(o_notify,
  157. NOTIFY_EVENT_MMD_EXT_CURRENT, 0);
  158. }
  159. }
  160. skip:
  161. return 0;
  162. }
  163. static void seek_usb_interface(struct usb_device *dev)
  164. {
  165. struct usb_interface *intf;
  166. int i;
  167. if (!dev) {
  168. unl_err("%s no dev\n", __func__);
  169. goto done;
  170. }
  171. if (!dev->actconfig) {
  172. unl_info("%s no set config\n", __func__);
  173. goto done;
  174. }
  175. for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
  176. intf = dev->actconfig->interface[i];
  177. /* You can use this function for various purposes */
  178. store_usblog_notify(NOTIFY_PORT_CLASS,
  179. (void *)&dev->descriptor.bDeviceClass,
  180. (void *)&intf->cur_altsetting->desc.bInterfaceClass);
  181. }
  182. done:
  183. return;
  184. }
  185. static void disconnect_usb_driver(struct usb_device *dev)
  186. {
  187. struct usb_interface *intf = NULL;
  188. struct usb_driver *driver = NULL;
  189. int i;
  190. if (!dev) {
  191. unl_err("%s no dev\n", __func__);
  192. goto done;
  193. }
  194. if (!dev->actconfig) {
  195. unl_err("%s no set config\n", __func__);
  196. goto done;
  197. }
  198. for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
  199. intf = dev->actconfig->interface[i];
  200. if (intf->dev.driver) {
  201. driver = to_usb_driver(intf->dev.driver);
  202. usb_driver_release_interface(driver, intf);
  203. }
  204. }
  205. done:
  206. return;
  207. }
  208. #ifndef CONFIG_DISABLE_LOCKSCREEN_USB_RESTRICTION
  209. static void connect_usb_driver(struct usb_device *dev)
  210. {
  211. struct usb_interface *intf = NULL;
  212. int i, ret = 0;
  213. if (!dev) {
  214. unl_err("%s no dev\n", __func__);
  215. goto done;
  216. }
  217. if (!dev->actconfig) {
  218. unl_err("%s no set config\n", __func__);
  219. goto done;
  220. }
  221. for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
  222. intf = dev->actconfig->interface[i];
  223. intf->authorized = 1;
  224. if (!intf->dev.driver) {
  225. ret = device_attach(&intf->dev);
  226. if (ret < 0)
  227. unl_err("%s attach intf->dev. error ret(%d)\n", __func__, ret);
  228. else
  229. unl_info("%s attach intf->dev\n", __func__);
  230. }
  231. }
  232. done:
  233. return;
  234. }
  235. static void intf_authorized_clear(struct usb_device *dev)
  236. {
  237. struct usb_hcd *hcd = bus_to_hcd(dev->bus);
  238. unl_info("%s\n", __func__);
  239. if (hcd)
  240. clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
  241. }
  242. #endif
  243. static int call_device_notify(struct usb_device *dev, int connect)
  244. {
  245. struct otg_notify *o_notify = get_otg_notify();
  246. #ifndef CONFIG_DISABLE_LOCKSCREEN_USB_RESTRICTION
  247. int ret = 0;
  248. #endif
  249. if (dev->bus->root_hub != dev) {
  250. if (connect) {
  251. unl_info("%s device\n", __func__);
  252. send_otg_notify(o_notify,
  253. NOTIFY_EVENT_DEVICE_CONNECT, 1);
  254. if (check_gamepad_device(dev))
  255. send_otg_notify(o_notify,
  256. NOTIFY_EVENT_GAMEPAD_CONNECT, 1);
  257. else if (check_lanhub_device(dev))
  258. send_otg_notify(o_notify,
  259. NOTIFY_EVENT_LANHUB_CONNECT, 1);
  260. else
  261. ;
  262. store_usblog_notify(NOTIFY_PORT_CONNECT,
  263. (void *)&dev->descriptor.idVendor,
  264. (void *)&dev->descriptor.idProduct);
  265. seek_usb_interface(dev);
  266. if (!usb_check_whitelist_for_mdm(dev)) {
  267. unl_info("This device will be disabled.\n");
  268. disconnect_usb_driver(dev);
  269. usb_set_device_state(dev, USB_STATE_NOTATTACHED);
  270. goto done;
  271. }
  272. switch (usb_check_whitelist_enable_state()) {
  273. case NOTIFY_MDM_NONE:
  274. /* whitelist_for_serial OFF, whitelist_for_id OFF */
  275. break;
  276. case NOTIFY_MDM_SERIAL:
  277. /* whitelist_for_serial ON, whitelist_for_id OFF */
  278. if (!usb_check_whitelist_for_serial(dev)) {
  279. unl_info("This device will be disabled.\n");
  280. disconnect_usb_driver(dev);
  281. usb_set_device_state(dev, USB_STATE_NOTATTACHED);
  282. }
  283. break;
  284. case NOTIFY_MDM_ID:
  285. /* whitelist_for_serial OFF, whitelist_for_id ON */
  286. if (!usb_check_whitelist_for_id(dev)) {
  287. unl_info("This device will be disabled.\n");
  288. disconnect_usb_driver(dev);
  289. usb_set_device_state(dev, USB_STATE_NOTATTACHED);
  290. }
  291. break;
  292. case NOTIFY_MDM_ID_AND_SERIAL:
  293. /* whitelist_for_serial ON, whitelist_for_id ON */
  294. if (!usb_check_whitelist_for_id(dev) &&
  295. !usb_check_whitelist_for_serial(dev)) {
  296. unl_info("This device will be disabled.\n");
  297. disconnect_usb_driver(dev);
  298. usb_set_device_state(dev, USB_STATE_NOTATTACHED);
  299. }
  300. break;
  301. default:
  302. break;
  303. }
  304. #ifndef CONFIG_DISABLE_LOCKSCREEN_USB_RESTRICTION
  305. ret = usb_check_allowlist_for_lockscreen_enabled_id(dev);
  306. if (ret == USB_NOTIFY_NOLIST) {
  307. unl_info("This device will be disabled.\n");
  308. disconnect_usb_driver(dev);
  309. usb_set_device_state(dev, USB_STATE_NOTATTACHED);
  310. dev->authorized = 0;
  311. } else if (ret == USB_NOTIFY_ALLOWLOST
  312. || ret == USB_NOTIFY_NORESTRICT) {
  313. connect_usb_driver(dev);
  314. }
  315. #endif
  316. } else {
  317. send_otg_notify(o_notify,
  318. NOTIFY_EVENT_DEVICE_CONNECT, 0);
  319. store_usblog_notify(NOTIFY_PORT_DISCONNECT,
  320. (void *)&dev->descriptor.idVendor,
  321. (void *)&dev->descriptor.idProduct);
  322. #ifndef CONFIG_DISABLE_LOCKSCREEN_USB_RESTRICTION
  323. if (!dev->authorized)
  324. disconnect_unauthorized_device(dev);
  325. #endif
  326. }
  327. } else {
  328. if (connect) {
  329. unl_info("%s root hub\n", __func__);
  330. #ifndef CONFIG_DISABLE_LOCKSCREEN_USB_RESTRICTION
  331. if (check_usb_restrict_lock_state(o_notify))
  332. intf_authorized_clear(dev);
  333. #endif
  334. }
  335. }
  336. done:
  337. return 0;
  338. }
  339. static void check_roothub_device(struct usb_device *dev, bool on)
  340. {
  341. struct otg_notify *o_notify = get_otg_notify();
  342. struct usb_device *hdev;
  343. struct usb_device *udev;
  344. int port = 0;
  345. int speed = USB_SPEED_UNKNOWN;
  346. int pr_speed = USB_SPEED_UNKNOWN;
  347. static int hs_hub;
  348. static int ss_hub;
  349. int con_hub = 0;
  350. if (!o_notify) {
  351. unl_err("%s otg_notify is null\n", __func__);
  352. return;
  353. }
  354. pr_speed = get_con_dev_max_speed(o_notify);
  355. hdev = dev->parent;
  356. if (!hdev)
  357. return;
  358. hdev = dev->bus->root_hub;
  359. if (!hdev)
  360. return;
  361. usb_hub_for_each_child(hdev, port, udev) {
  362. if (!on && (udev == dev))
  363. continue;
  364. #if defined(CONFIG_USB_HW_PARAM)
  365. if (is_known_usbaudio(udev))
  366. inc_hw_param(o_notify, USB_HOST_CLASS_AUDIO_SAMSUNG_COUNT);
  367. #endif
  368. if (is_usbhub(udev))
  369. con_hub = 1;
  370. if (udev->speed > speed)
  371. speed = udev->speed;
  372. }
  373. if (hdev->speed >= USB_SPEED_SUPER) {
  374. if (speed > USB_SPEED_UNKNOWN)
  375. ss_hub = 1;
  376. else
  377. ss_hub = 0;
  378. } else if (hdev->speed > USB_SPEED_UNKNOWN
  379. && hdev->speed != USB_SPEED_WIRELESS) {
  380. if (speed > USB_SPEED_UNKNOWN)
  381. hs_hub = 1;
  382. else
  383. hs_hub = 0;
  384. } else
  385. ;
  386. if (ss_hub || hs_hub) {
  387. if (speed > pr_speed)
  388. set_con_dev_max_speed(o_notify, speed);
  389. } else
  390. set_con_dev_max_speed(o_notify, USB_SPEED_UNKNOWN);
  391. unl_info("%s : dev->speed %s %s\n", __func__,
  392. usb_speed_string(dev->speed), on ? "on" : "off");
  393. unl_info("%s : o_notify->speed %s\n", __func__,
  394. usb_speed_string(get_con_dev_max_speed(o_notify)));
  395. set_con_dev_hub(o_notify, speed, con_hub);
  396. }
  397. #if defined(CONFIG_USB_HW_PARAM)
  398. static int set_hw_param(struct usb_device *dev)
  399. {
  400. struct otg_notify *o_notify = get_otg_notify();
  401. int ret = 0;
  402. int bInterfaceClass = 0, speed = 0;
  403. if (o_notify == NULL || dev->config->interface[0] == NULL) {
  404. ret = -EFAULT;
  405. goto err;
  406. }
  407. if (dev->bus->root_hub != dev) {
  408. bInterfaceClass
  409. = dev->config->interface[0]
  410. ->cur_altsetting->desc.bInterfaceClass;
  411. speed = dev->speed;
  412. unl_info("%s USB device connected - Class : 0x%x, speed : 0x%x\n",
  413. __func__, bInterfaceClass, speed);
  414. if (bInterfaceClass == USB_CLASS_AUDIO)
  415. inc_hw_param(o_notify, USB_HOST_CLASS_AUDIO_COUNT);
  416. else if (bInterfaceClass == USB_CLASS_COMM)
  417. inc_hw_param(o_notify, USB_HOST_CLASS_COMM_COUNT);
  418. else if (bInterfaceClass == USB_CLASS_HID)
  419. inc_hw_param(o_notify, USB_HOST_CLASS_HID_COUNT);
  420. else if (bInterfaceClass == USB_CLASS_PHYSICAL)
  421. inc_hw_param(o_notify, USB_HOST_CLASS_PHYSICAL_COUNT);
  422. else if (bInterfaceClass == USB_CLASS_STILL_IMAGE)
  423. inc_hw_param(o_notify, USB_HOST_CLASS_IMAGE_COUNT);
  424. else if (bInterfaceClass == USB_CLASS_PRINTER)
  425. inc_hw_param(o_notify, USB_HOST_CLASS_PRINTER_COUNT);
  426. else if (bInterfaceClass == USB_CLASS_MASS_STORAGE) {
  427. inc_hw_param(o_notify, USB_HOST_CLASS_STORAGE_COUNT);
  428. if (speed == USB_SPEED_SUPER)
  429. inc_hw_param(o_notify,
  430. USB_HOST_STORAGE_SUPER_COUNT);
  431. else if (speed == USB_SPEED_HIGH)
  432. inc_hw_param(o_notify,
  433. USB_HOST_STORAGE_HIGH_COUNT);
  434. else if (speed == USB_SPEED_FULL)
  435. inc_hw_param(o_notify,
  436. USB_HOST_STORAGE_FULL_COUNT);
  437. } else if (bInterfaceClass == USB_CLASS_HUB)
  438. inc_hw_param(o_notify, USB_HOST_CLASS_HUB_COUNT);
  439. else if (bInterfaceClass == USB_CLASS_CDC_DATA)
  440. inc_hw_param(o_notify, USB_HOST_CLASS_CDC_COUNT);
  441. else if (bInterfaceClass == USB_CLASS_CSCID)
  442. inc_hw_param(o_notify, USB_HOST_CLASS_CSCID_COUNT);
  443. else if (bInterfaceClass == USB_CLASS_CONTENT_SEC)
  444. inc_hw_param(o_notify, USB_HOST_CLASS_CONTENT_COUNT);
  445. else if (bInterfaceClass == USB_CLASS_VIDEO)
  446. inc_hw_param(o_notify, USB_HOST_CLASS_VIDEO_COUNT);
  447. else if (bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER)
  448. inc_hw_param(o_notify, USB_HOST_CLASS_WIRELESS_COUNT);
  449. else if (bInterfaceClass == USB_CLASS_MISC)
  450. inc_hw_param(o_notify, USB_HOST_CLASS_MISC_COUNT);
  451. else if (bInterfaceClass == USB_CLASS_APP_SPEC)
  452. inc_hw_param(o_notify, USB_HOST_CLASS_APP_COUNT);
  453. else if (bInterfaceClass == USB_CLASS_VENDOR_SPEC)
  454. inc_hw_param(o_notify, USB_HOST_CLASS_VENDOR_COUNT);
  455. if (speed == USB_SPEED_SUPER)
  456. inc_hw_param(o_notify, USB_HOST_SUPER_SPEED_COUNT);
  457. else if (speed == USB_SPEED_HIGH)
  458. inc_hw_param(o_notify, USB_HOST_HIGH_SPEED_COUNT);
  459. else if (speed == USB_SPEED_FULL)
  460. inc_hw_param(o_notify, USB_HOST_FULL_SPEED_COUNT);
  461. else if (speed == USB_SPEED_LOW)
  462. inc_hw_param(o_notify, USB_HOST_LOW_SPEED_COUNT);
  463. }
  464. err:
  465. return ret;
  466. }
  467. #endif
  468. static void check_unsupport_device(struct usb_device *dev)
  469. {
  470. struct dev_table *id;
  471. /* check VID, PID */
  472. for (id = unsupport_device_table; id->dev.match_flags; id++) {
  473. if ((id->dev.match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
  474. (id->dev.match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
  475. id->dev.idVendor == le16_to_cpu(dev->descriptor.idVendor) &&
  476. id->dev.idProduct == le16_to_cpu(dev->descriptor.idProduct)) {
  477. #if defined(CONFIG_USB_HOST_CERTI)
  478. send_usb_certi_uevent(USB_CERTI_UNSUPPORT_ACCESSORY);
  479. #endif
  480. break;
  481. }
  482. }
  483. }
  484. static int dev_notify(struct notifier_block *self,
  485. unsigned long action, void *dev)
  486. {
  487. switch (action) {
  488. case USB_DEVICE_ADD:
  489. call_device_notify(dev, 1);
  490. call_battery_notify(dev, 1);
  491. check_roothub_device(dev, 1);
  492. #if defined(CONFIG_USB_HW_PARAM)
  493. set_hw_param(dev);
  494. #endif
  495. check_unsupport_device(dev);
  496. check_usbaudio(dev);
  497. check_usbgroup(dev);
  498. break;
  499. case USB_DEVICE_REMOVE:
  500. call_device_notify(dev, 0);
  501. call_battery_notify(dev, 0);
  502. check_roothub_device(dev, 0);
  503. break;
  504. }
  505. return NOTIFY_OK;
  506. }
  507. static struct notifier_block dev_nb = {
  508. .notifier_call = dev_notify,
  509. };
  510. void register_usbdev_notify(void)
  511. {
  512. usb_register_notify(&dev_nb);
  513. }
  514. EXPORT_SYMBOL(register_usbdev_notify);
  515. void unregister_usbdev_notify(void)
  516. {
  517. usb_unregister_notify(&dev_nb);
  518. }
  519. EXPORT_SYMBOL(unregister_usbdev_notify);