.. | .. |
---|
828 | 828 | if (ret) |
---|
829 | 829 | return ret; |
---|
830 | 830 | |
---|
831 | | - snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD", |
---|
832 | | - hdev->product, &serial); |
---|
| 831 | + snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial); |
---|
833 | 832 | dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq); |
---|
834 | 833 | |
---|
835 | 834 | name = hidpp_unifying_get_name(hidpp); |
---|
.. | .. |
---|
919 | 918 | print_version: |
---|
920 | 919 | hid_info(hidpp->hid_dev, "HID++ %u.%u device connected.\n", |
---|
921 | 920 | hidpp->protocol_major, hidpp->protocol_minor); |
---|
| 921 | + return 0; |
---|
| 922 | +} |
---|
| 923 | + |
---|
| 924 | +/* -------------------------------------------------------------------------- */ |
---|
| 925 | +/* 0x0003: Device Information */ |
---|
| 926 | +/* -------------------------------------------------------------------------- */ |
---|
| 927 | + |
---|
| 928 | +#define HIDPP_PAGE_DEVICE_INFORMATION 0x0003 |
---|
| 929 | + |
---|
| 930 | +#define CMD_GET_DEVICE_INFO 0x00 |
---|
| 931 | + |
---|
| 932 | +static int hidpp_get_serial(struct hidpp_device *hidpp, u32 *serial) |
---|
| 933 | +{ |
---|
| 934 | + struct hidpp_report response; |
---|
| 935 | + u8 feature_type; |
---|
| 936 | + u8 feature_index; |
---|
| 937 | + int ret; |
---|
| 938 | + |
---|
| 939 | + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_DEVICE_INFORMATION, |
---|
| 940 | + &feature_index, |
---|
| 941 | + &feature_type); |
---|
| 942 | + if (ret) |
---|
| 943 | + return ret; |
---|
| 944 | + |
---|
| 945 | + ret = hidpp_send_fap_command_sync(hidpp, feature_index, |
---|
| 946 | + CMD_GET_DEVICE_INFO, |
---|
| 947 | + NULL, 0, &response); |
---|
| 948 | + if (ret) |
---|
| 949 | + return ret; |
---|
| 950 | + |
---|
| 951 | + /* See hidpp_unifying_get_serial() */ |
---|
| 952 | + *serial = *((u32 *)&response.rap.params[1]); |
---|
| 953 | + return 0; |
---|
| 954 | +} |
---|
| 955 | + |
---|
| 956 | +static int hidpp_serial_init(struct hidpp_device *hidpp) |
---|
| 957 | +{ |
---|
| 958 | + struct hid_device *hdev = hidpp->hid_dev; |
---|
| 959 | + u32 serial; |
---|
| 960 | + int ret; |
---|
| 961 | + |
---|
| 962 | + ret = hidpp_get_serial(hidpp, &serial); |
---|
| 963 | + if (ret) |
---|
| 964 | + return ret; |
---|
| 965 | + |
---|
| 966 | + snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial); |
---|
| 967 | + dbg_hid("HID++ DeviceInformation: Got serial: %s\n", hdev->uniq); |
---|
| 968 | + |
---|
922 | 969 | return 0; |
---|
923 | 970 | } |
---|
924 | 971 | |
---|
.. | .. |
---|
3763 | 3810 | bool connected; |
---|
3764 | 3811 | unsigned int connect_mask = HID_CONNECT_DEFAULT; |
---|
3765 | 3812 | struct hidpp_ff_private_data data; |
---|
| 3813 | + bool will_restart = false; |
---|
3766 | 3814 | |
---|
3767 | 3815 | /* report_fixup needs drvdata to be set before we call hid_parse */ |
---|
3768 | 3816 | hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL); |
---|
.. | .. |
---|
3818 | 3866 | return ret; |
---|
3819 | 3867 | } |
---|
3820 | 3868 | |
---|
| 3869 | + if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT || |
---|
| 3870 | + hidpp->quirks & HIDPP_QUIRK_UNIFYING) |
---|
| 3871 | + will_restart = true; |
---|
| 3872 | + |
---|
3821 | 3873 | INIT_WORK(&hidpp->work, delayed_work_cb); |
---|
3822 | 3874 | mutex_init(&hidpp->send_mutex); |
---|
3823 | 3875 | init_waitqueue_head(&hidpp->wait); |
---|
.. | .. |
---|
3832 | 3884 | * Plain USB connections need to actually call start and open |
---|
3833 | 3885 | * on the transport driver to allow incoming data. |
---|
3834 | 3886 | */ |
---|
3835 | | - ret = hid_hw_start(hdev, 0); |
---|
| 3887 | + ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask); |
---|
3836 | 3888 | if (ret) { |
---|
3837 | 3889 | hid_err(hdev, "hw start failed\n"); |
---|
3838 | 3890 | goto hid_hw_start_fail; |
---|
.. | .. |
---|
3850 | 3902 | |
---|
3851 | 3903 | if (hidpp->quirks & HIDPP_QUIRK_UNIFYING) |
---|
3852 | 3904 | hidpp_unifying_init(hidpp); |
---|
| 3905 | + else if (hid_is_usb(hidpp->hid_dev)) |
---|
| 3906 | + hidpp_serial_init(hidpp); |
---|
3853 | 3907 | |
---|
3854 | 3908 | connected = hidpp_root_get_protocol_version(hidpp) == 0; |
---|
3855 | 3909 | atomic_set(&hidpp->connected, connected); |
---|
.. | .. |
---|
3869 | 3923 | hidpp->wireless_feature_index = 0; |
---|
3870 | 3924 | else if (ret) |
---|
3871 | 3925 | goto hid_hw_init_fail; |
---|
| 3926 | + ret = 0; |
---|
3872 | 3927 | } |
---|
3873 | 3928 | |
---|
3874 | 3929 | if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { |
---|
.. | .. |
---|
3883 | 3938 | |
---|
3884 | 3939 | hidpp_connect_event(hidpp); |
---|
3885 | 3940 | |
---|
3886 | | - /* Reset the HID node state */ |
---|
3887 | | - hid_device_io_stop(hdev); |
---|
3888 | | - hid_hw_close(hdev); |
---|
3889 | | - hid_hw_stop(hdev); |
---|
| 3941 | + if (will_restart) { |
---|
| 3942 | + /* Reset the HID node state */ |
---|
| 3943 | + hid_device_io_stop(hdev); |
---|
| 3944 | + hid_hw_close(hdev); |
---|
| 3945 | + hid_hw_stop(hdev); |
---|
3890 | 3946 | |
---|
3891 | | - if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) |
---|
3892 | | - connect_mask &= ~HID_CONNECT_HIDINPUT; |
---|
| 3947 | + if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) |
---|
| 3948 | + connect_mask &= ~HID_CONNECT_HIDINPUT; |
---|
3893 | 3949 | |
---|
3894 | | - /* Now export the actual inputs and hidraw nodes to the world */ |
---|
3895 | | - ret = hid_hw_start(hdev, connect_mask); |
---|
3896 | | - if (ret) { |
---|
3897 | | - hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); |
---|
3898 | | - goto hid_hw_start_fail; |
---|
| 3950 | + /* Now export the actual inputs and hidraw nodes to the world */ |
---|
| 3951 | + ret = hid_hw_start(hdev, connect_mask); |
---|
| 3952 | + if (ret) { |
---|
| 3953 | + hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); |
---|
| 3954 | + goto hid_hw_start_fail; |
---|
| 3955 | + } |
---|
3899 | 3956 | } |
---|
3900 | 3957 | |
---|
3901 | 3958 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { |
---|
.. | .. |
---|
3952 | 4009 | { /* wireless touchpad T651 */ |
---|
3953 | 4010 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, |
---|
3954 | 4011 | USB_DEVICE_ID_LOGITECH_T651), |
---|
3955 | | - .driver_data = HIDPP_QUIRK_CLASS_WTP }, |
---|
| 4012 | + .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT }, |
---|
3956 | 4013 | { /* Mouse Logitech Anywhere MX */ |
---|
3957 | 4014 | LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, |
---|
3958 | 4015 | { /* Mouse Logitech Cube */ |
---|