From 8552290becac51a89c9ff54dc82e6b2b896d4015 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 13 Jun 2022 16:05:18 +0200 Subject: [PATCH] goodix: Reset device if storage listing fails When opening the device, query the stored prints. This should usually always succeed (and it should be fast). If it fails, then we are very likely dealing with a corrupted template storage on the device. In that case, emit the command to clear the storage in order to reset the device and get it back into a usable state. --- libfprint/drivers/goodixmoc/goodix.c | 65 +++++++++++++++++++++++++++ libfprint/drivers/goodixmoc/goodix.h | 2 + tests/goodixmoc/custom.pcapng | Bin 61764 -> 73120 bytes tests/goodixmoc/custom.py | 3 ++ tests/goodixmoc/device | 57 +++++++++++------------ 5 files changed, 99 insertions(+), 28 deletions(-) diff --git a/libfprint/drivers/goodixmoc/goodix.c b/libfprint/drivers/goodixmoc/goodix.c index e892b707..cfc69c94 100644 --- a/libfprint/drivers/goodixmoc/goodix.c +++ b/libfprint/drivers/goodixmoc/goodix.c @@ -1041,6 +1041,47 @@ fp_init_config_cb (FpiDeviceGoodixMoc *self, fpi_ssm_next_state (self->task_ssm); } +static void +fp_init_cb_reset_or_complete (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fp_warn ("Template storage appears to have been corrupted! Error was: %s", error->message); + fp_warn ("A known reason for this to happen is a firmware bug triggered by another storage area being initialized."); + fpi_ssm_jump_to_state (self->task_ssm, FP_INIT_RESET_DEVICE); + } + else + { + fpi_ssm_mark_completed (self->task_ssm); + } +} + +static void +fp_init_reset_device_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fp_warn ("Reset failed: %s", error->message); + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + if ((resp->result >= GX_FAILED) && (resp->result != GX_ERROR_FINGER_ID_NOEXIST)) + { + fp_warn ("Reset failed, device reported: 0x%x", resp->result); + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, + "Failed clear storage, result: 0x%x", + resp->result)); + return; + } + + fp_warn ("Reset completed"); + fpi_ssm_mark_completed (self->task_ssm); +} static void fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device) @@ -1065,6 +1106,30 @@ fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device) sizeof (gxfp_sensor_cfg_t), fp_init_config_cb); break; + + case FP_INIT_TEMPLATE_LIST: + /* List prints to check whether the template DB was corrupted. + * As of 2022-06-13 there is a known firmware issue that can cause the + * stored templates for Linux to be corrupted when the Windows storage + * area is initialized. + * In that case, we'll get a protocol failure trying to retrieve the + * list of prints. + */ + goodix_sensor_cmd (self, MOC_CMD0_GETFINGERLIST, MOC_CMD1_DEFAULT, + FALSE, + (const guint8 *) &dummy, + 1, + fp_init_cb_reset_or_complete); + break; + + case FP_INIT_RESET_DEVICE: + fp_warn ("Resetting device storage, you will need to enroll all prints again!"); + goodix_sensor_cmd (self, MOC_CMD0_DELETETEMPLATE, MOC_CMD1_DELETE_ALL, + FALSE, + NULL, + 0, + fp_init_reset_device_cb); + break; } diff --git a/libfprint/drivers/goodixmoc/goodix.h b/libfprint/drivers/goodixmoc/goodix.h index 23e142ac..56b2d171 100644 --- a/libfprint/drivers/goodixmoc/goodix.h +++ b/libfprint/drivers/goodixmoc/goodix.h @@ -35,6 +35,8 @@ typedef enum { typedef enum { FP_INIT_VERSION = 0, FP_INIT_CONFIG, + FP_INIT_TEMPLATE_LIST, + FP_INIT_RESET_DEVICE, FP_INIT_NUM_STATES, } FpInitState; diff --git a/tests/goodixmoc/custom.pcapng b/tests/goodixmoc/custom.pcapng index eb58d865e5516dc652fdbe299dc5ebd94f377d79..b5e2d89c75a7253571360a9e064bb31259834e2d 100644 GIT binary patch literal 73120 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

L4zz?BJ>h*kk0r(^u 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 QJ9pd8@{S6L6%17Se}dI!Qvd(} literal 61764 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 XA9BL*ba>_@+GdQ={*Uef)B^oq$y{Nf diff --git a/tests/goodixmoc/custom.py b/tests/goodixmoc/custom.py index 1fb513a1..38fdd26c 100755 --- a/tests/goodixmoc/custom.py +++ b/tests/goodixmoc/custom.py @@ -25,6 +25,9 @@ assert d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR) d.open_sync() +# 1. verify clear storage command, 2. make sure later asserts are good +d.clear_storage_sync() + template = FPrint.Print.new(d) def enroll_progress(*args): diff --git a/tests/goodixmoc/device b/tests/goodixmoc/device index 9fb39e59..1e209a1d 100644 --- a/tests/goodixmoc/device +++ b/tests/goodixmoc/device @@ -1,14 +1,14 @@ P: /devices/pci0000:00/0000:00:14.0/usb1/1-3 -N: bus/usb/001/053=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000 -E: DEVNAME=/dev/bus/usb/001/053 +N: bus/usb/001/023=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000 +E: DEVNAME=/dev/bus/usb/001/023 E: DEVTYPE=usb_device E: DRIVER=usb E: PRODUCT=27c6/6496/100 E: TYPE=239/0/0 E: BUSNUM=001 -E: DEVNUM=053 +E: DEVNUM=023 E: MAJOR=189 -E: MINOR=52 +E: MINOR=22 E: SUBSYSTEM=usb E: ID_VENDOR=Goodix_Technology_Co.__Ltd. E: ID_VENDOR_ENC=Goodix\x20Technology\x20Co.\x2c\x20Ltd. @@ -23,6 +23,7 @@ E: ID_BUS=usb E: ID_USB_INTERFACES=:ff0000: E: ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd. E: ID_AUTOSUSPEND=1 +E: ID_PERSIST=0 E: ID_PATH=pci-0000:00:14.0-usb-0:3 E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_3 A: authorized=1\n @@ -40,8 +41,8 @@ A: bmAttributes=a0\n A: busnum=1\n A: configuration=XXXX_MOC_B0\n H: descriptors=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000 -A: dev=189:52\n -A: devnum=53\n +A: dev=189:22\n +A: devnum=23\n A: devpath=3\n L: driver=../../../../../bus/usb/drivers/usb L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d/device:20 @@ -51,16 +52,16 @@ A: ltm_capable=no\n A: manufacturer=Goodix Technology Co., Ltd.\n A: maxchild=0\n L: port=../1-0:1.0/usb1-port3 -A: power/active_duration=29262\n +A: power/active_duration=22667\n A: power/autosuspend=2\n A: power/autosuspend_delay_ms=2000\n -A: power/connected_duration=57399\n +A: power/connected_duration=917616\n A: power/control=auto\n A: power/level=auto\n A: power/persist=1\n -A: power/runtime_active_time=29308\n +A: power/runtime_active_time=22809\n A: power/runtime_status=active\n -A: power/runtime_suspended_time=27850\n +A: power/runtime_suspended_time=894564\n A: power/wakeup=disabled\n A: power/wakeup_abort_count=\n A: power/wakeup_active=\n @@ -77,29 +78,29 @@ A: rx_lanes=1\n A: serial=XXXX_MOC_B0\n A: speed=12\n A: tx_lanes=1\n -A: urbnum=394\n +A: urbnum=298\n A: version= 2.00\n P: /devices/pci0000:00/0000:00:14.0/usb1 -N: bus/usb/001/001=12010002090001406B1D020013050302010109021900010100E0000904000001090000000705810304000C +N: bus/usb/001/001=12010002090001406B1D020017050302010109021900010100E0000904000001090000000705810304000C E: DEVNAME=/dev/bus/usb/001/001 E: DEVTYPE=usb_device E: DRIVER=usb -E: PRODUCT=1d6b/2/513 +E: PRODUCT=1d6b/2/517 E: TYPE=9/0/1 E: BUSNUM=001 E: DEVNUM=001 E: MAJOR=189 E: MINOR=0 E: SUBSYSTEM=usb -E: ID_VENDOR=Linux_5.13.15-200.fc34.x86_64_xhci-hcd -E: ID_VENDOR_ENC=Linux\x205.13.15-200.fc34.x86_64\x20xhci-hcd +E: ID_VENDOR=Linux_5.17.12-300.fc36.x86_64_xhci-hcd +E: ID_VENDOR_ENC=Linux\x205.17.12-300.fc36.x86_64\x20xhci-hcd E: ID_VENDOR_ID=1d6b E: ID_MODEL=xHCI_Host_Controller E: ID_MODEL_ENC=xHCI\x20Host\x20Controller E: ID_MODEL_ID=0002 -E: ID_REVISION=0513 -E: ID_SERIAL=Linux_5.13.15-200.fc34.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 +E: ID_REVISION=0517 +E: ID_SERIAL=Linux_5.17.12-300.fc36.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 E: ID_SERIAL_SHORT=0000:00:14.0 E: ID_BUS=usb E: ID_USB_INTERFACES=:090000: @@ -122,11 +123,11 @@ A: bMaxPacketSize0=64\n A: bMaxPower=0mA\n A: bNumConfigurations=1\n A: bNumInterfaces= 1\n -A: bcdDevice=0513\n +A: bcdDevice=0517\n A: bmAttributes=e0\n A: busnum=1\n A: configuration=\n -H: descriptors=12010002090001406B1D020013050302010109021900010100E0000904000001090000000705810304000C +H: descriptors=12010002090001406B1D020017050302010109021900010100E0000904000001090000000705810304000C A: dev=189:0\n A: devnum=1\n A: devpath=0\n @@ -136,15 +137,15 @@ A: idProduct=0002\n A: idVendor=1d6b\n A: interface_authorized_default=1\n A: ltm_capable=no\n -A: manufacturer=Linux 5.13.15-200.fc34.x86_64 xhci-hcd\n +A: manufacturer=Linux 5.17.12-300.fc36.x86_64 xhci-hcd\n A: maxchild=12\n -A: power/active_duration=219578717\n +A: power/active_duration=164289796\n A: power/autosuspend=0\n A: power/autosuspend_delay_ms=0\n -A: power/connected_duration=219649620\n +A: power/connected_duration=164360220\n A: power/control=auto\n A: power/level=auto\n -A: power/runtime_active_time=219589127\n +A: power/runtime_active_time=164331876\n A: power/runtime_status=active\n A: power/runtime_suspended_time=0\n A: power/wakeup=disabled\n @@ -163,14 +164,14 @@ A: rx_lanes=1\n A: serial=0000:00:14.0\n A: speed=480\n A: tx_lanes=1\n -A: urbnum=4325\n +A: urbnum=2097\n A: version= 2.00\n P: /devices/pci0000:00/0000:00:14.0 E: DRIVER=xhci_hcd E: PCI_CLASS=C0330 E: PCI_ID=8086:9DED -E: PCI_SUBSYS_ID=17AA:2292\n +E: PCI_SUBSYS_ID=17AA:2292 E: PCI_SLOT_NAME=0000:00:14.0 E: MODALIAS=pci:v00008086d00009DEDsv000017AAsd00002292bc0Csc03i30 E: SUBSYSTEM=pci @@ -183,7 +184,7 @@ E: ID_MODEL_FROM_DATABASE=Cannon Point-LP USB 3.1 xHCI Controller A: ari_enabled=0\n A: broken_parity_status=0\n A: class=0x0c0330\n -H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F000000004C084B0100000000316000000000000000000000000000000180C2C1080000000000000000000000059087001803E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000000000000000000008000000040000000000000000000000000000000000000000000000000000000800000004000000000000000000000000000000000000000000000000000000B50F320112000000 +H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F00000000F507312600000000316000000000000000000000000000000180C2C1080000000000000000000000059087001803E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000000000000000000008000000040000000000000000000000000000000000000000000000000000000800000004000000000000000000000000000000000000000000000000000000B50F320112000000 A: consistent_dma_mask_bits=64\n A: d3cold_allowed=1\n A: dbc=disabled\n @@ -201,8 +202,8 @@ A: msi_bus=1\n A: msi_irqs/128=msi\n A: numa_node=-1\n A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 11 12 2112 12\nxHCI ring segments 46 50 4096 50\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 6 32 128 1\nbuffer-32 0 0 32 0\n -A: power/control=on\n -A: power/runtime_active_time=219589302\n +A: power/control=auto\n +A: power/runtime_active_time=164332777\n A: power/runtime_status=active\n A: power/runtime_suspended_time=0\n A: power/wakeup=enabled\n