From 979e502ca555b19cc2fdc65b25020396ba7190bf Mon Sep 17 00:00:00 2001 From: mikee512 Date: Mon, 26 May 2025 15:53:40 -0400 Subject: [PATCH] Cleanup and remove ec_max_xxx --- libfprint/drivers/crfpmoc/crfpmoc.c | 858 ++++++++++++++-------------- tests/crfpmoc/custom.ioctl | 9 +- tests/crfpmoc/device | 76 +-- 3 files changed, 475 insertions(+), 468 deletions(-) diff --git a/libfprint/drivers/crfpmoc/crfpmoc.c b/libfprint/drivers/crfpmoc/crfpmoc.c index 025ae8db..a3208e54 100644 --- a/libfprint/drivers/crfpmoc/crfpmoc.c +++ b/libfprint/drivers/crfpmoc/crfpmoc.c @@ -35,6 +35,10 @@ struct _FpiDeviceCrfpMoc GCancellable *interrupt_cancellable; int fd; int emul_fd; + guint16 max_insize; + guint16 max_outsize; + guint16 max_templates; + guint16 template_size; }; G_DEFINE_TYPE (FpiDeviceCrfpMoc, fpi_device_crfpmoc, FP_TYPE_DEVICE) @@ -77,8 +81,6 @@ static const FpIdEntry crfpmoc_id_table[] = { #define CRFPMOC_PRINT_DATA_VARIANT_FMT "(@ay@ayqq)" #define CRFPMOC_PRINT_DATA_VARIANT_PRINT_ID 0 #define CRFPMOC_PRINT_DATA_VARIANT_TEMPLATE 1 -#define CRFPMOC_PRINT_DATA_VARIANT_MAX_OUTSIZE 2 -#define CRFPMOC_PRINT_DATA_VARIANT_MAX_TEMPLATES 3 /* Clear and free the state machine private data */ @@ -194,7 +196,7 @@ crfpmoc_mkbp_event_strresult (int i) } static char * -get_print_data_descriptor (FpPrint *print, gint8 template) +crfpmoc_get_print_data_descriptor (FpPrint *print, gint8 template) { const char *driver; const char *dev_id; @@ -208,9 +210,7 @@ get_print_data_descriptor (FpPrint *print, gint8 template) static void crfpmoc_set_print_data (FpPrint *print, gint8 template_idx, - guint8 *template, size_t template_size, - guint16 ec_max_outsize, - guint16 max_templates) + guint8 *template, size_t template_size) { fp_dbg ("Setting print data"); @@ -223,14 +223,13 @@ crfpmoc_set_print_data (FpPrint *print, gint8 template_idx, fpi_print_set_type (print, FPI_PRINT_RAW); - descr = get_print_data_descriptor (print, template_idx); + descr = crfpmoc_get_print_data_descriptor (print, template_idx); descr_len = descr ? strlen (descr) : 0; fp_dbg ("template id %d, descr %p (%s)", template_idx, descr, descr ? descr : ""); - // TODO: technically this is a guint8, not gchar */ print_id_var = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, descr, - descr_len, sizeof (guchar)); + descr_len, sizeof (guint8)); if (template == NULL || template_size == 0) template_var = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, NULL, 0, @@ -239,20 +238,17 @@ crfpmoc_set_print_data (FpPrint *print, gint8 template_idx, template_var = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, template, template_size, sizeof (guint8)); - fp_dbg ("EC max outsize: %d, max templates: %d, template %p, size %zd", - ec_max_outsize, max_templates, template, template_size); + fp_dbg ("crfpmoc_set_print_data: template %p, size %zd", + template, template_size); - fpi_data = g_variant_new (CRFPMOC_PRINT_DATA_VARIANT_FMT, print_id_var, template_var, - ec_max_outsize, max_templates); + fpi_data = g_variant_new (CRFPMOC_PRINT_DATA_VARIANT_FMT, print_id_var, template_var); g_object_set (print, "fpi-data", fpi_data, NULL); } static void crfpmoc_get_print_data (FpPrint *print, guint8 **template, - size_t *template_size, - guint16 *ec_max_outsize, - guint16 *max_templates) + size_t *template_size) { g_autoptr(GVariant) fpi_data = NULL; g_autoptr(GVariant) template_var = NULL; @@ -266,10 +262,6 @@ crfpmoc_get_print_data (FpPrint *print, guint8 **template, *template = NULL; if (template_size) *template_size = 0; - if (ec_max_outsize) - *ec_max_outsize = 0; - if (max_templates) - *max_templates = 0; g_object_get (print, "fpi-data", &fpi_data, NULL); if (!fpi_data) @@ -291,45 +283,10 @@ crfpmoc_get_print_data (FpPrint *print, guint8 **template, if ((template_var = g_variant_get_child_value (fpi_data, CRFPMOC_PRINT_DATA_VARIANT_TEMPLATE)) == NULL) - fp_warn ("no template data in print!!"); - - if (ec_max_outsize) { - g_autoptr(GVariant) variant_ec_max = - g_variant_get_child_value (fpi_data, - CRFPMOC_PRINT_DATA_VARIANT_MAX_OUTSIZE); - if (variant_ec_max) - { - *ec_max_outsize = g_variant_get_uint16 (variant_ec_max); - fp_dbg ("Extracted ec_max_outsize: %d", *ec_max_outsize); - } - else - { - fp_warn ("Failed to extract ec_max_outsize from GVariant"); - } + fp_warn ("no template data in print!!"); } - - if (max_templates) - { - g_autoptr(GVariant) variant_max_templates = - g_variant_get_child_value (fpi_data, - CRFPMOC_PRINT_DATA_VARIANT_MAX_TEMPLATES); - if (variant_max_templates) - { - *max_templates = g_variant_get_uint16 (variant_max_templates); - fp_dbg ("Extracted max_templates: %d", *max_templates); - } - else - { - fp_warn ("Failed to extract max_templates from GVariant"); - } - } - - fp_dbg ("EC max outsize: %d, max templates: %d", - ec_max_outsize ? *ec_max_outsize : 0, - max_templates ? *max_templates : 0); - - if (template_var) + else { template_data = g_variant_get_fixed_array (template_var, &template_data_size, sizeof (guint8)); @@ -633,6 +590,11 @@ rearm_out: #endif } +/* Enable device event reporting and queue a callback when there is + * data available to read. The device will notify on mode changes + * EC_FP_MODE_MATCH, EC_FP_MODE_ENROLL_*, EC_FP_MODE_CAPTURE, + * EC_FP_MODE_FINGER_UP, EC_FP_MODE_FINGER_DOWN, maybe others ? + */ static void crfpmoc_ec_pollevent (FpiSsm *ssm, unsigned long mask) { @@ -652,6 +614,8 @@ crfpmoc_ec_pollevent (FpiSsm *ssm, unsigned long mask) fp_dbg ("crfpmoc_ec_pollevent: created poll source %d", data->poll); } +/* Set the device to the specified mode, see above for list of modes. + */ static gboolean crfpmoc_cmd_fp_mode (FpiDeviceCrfpMoc *self, guint32 inmode, guint32 *outmode, GError **error) @@ -673,6 +637,11 @@ crfpmoc_cmd_fp_mode (FpiDeviceCrfpMoc *self, guint32 inmode, return TRUE; } +/* The device needs to have a seed set or it will not match. It is + * not clear when the seed is invalidated so we check if it is set + * prior to making this call. The call will fail if the seed is + * already set. + */ static gboolean crfpmoc_cmd_fp_seed (FpiDeviceCrfpMoc *self, const char *seed, GError **error) @@ -702,6 +671,12 @@ crfpmoc_cmd_fp_seed (FpiDeviceCrfpMoc *self, const char *seed, return TRUE; } +/* Set the device context. This seems to impact the encryption but it + * is not clear if we should use a print specific seed (like the + * print id) or a global value. We opt for the latter here. + * + * Note: setting the context will remove all templates. + */ // TODO: should this be converted to a sub state machine instead of // the sync completion ? static gboolean @@ -788,9 +763,15 @@ crfpmoc_fp_set_context (FpiDeviceCrfpMoc *self, return FALSE; } +/* Get the device info, vendor, version, etc. Get the state of the + * loaded templates and how many can be loaded as well as the size + * of templates. All templates have the same size on a given device. + */ static gboolean crfpmoc_cmd_fp_info (FpiDeviceCrfpMoc *self, guint16 *enrolled_templates, + guint16 *max_templates, + guint16 *template_size, GError **error) { struct crfpmoc_ec_response_fp_info r; @@ -833,10 +814,20 @@ crfpmoc_cmd_fp_info (FpiDeviceCrfpMoc *self, r.template_version, r.template_size, r.template_valid, r.template_max, r.template_dirty); - *enrolled_templates = r.template_valid; + if (enrolled_templates) + *enrolled_templates = r.template_valid; + if (max_templates) + *max_templates = r.template_max; + if (template_size) + *template_size = r.template_size; return TRUE; } +/* Get the current device statistics. This returns the match information + * time of last capture, etc. This can be used to determine if the last + * match was successful (as done in ectool). The completion MKBP event + * also seems to return the match status so perhaps that could be used. + */ static gboolean crfpmoc_cmd_fp_stats (FpiDeviceCrfpMoc *self, gint8 *template_idx, GError **error) @@ -875,6 +866,9 @@ crfpmoc_cmd_fp_stats (FpiDeviceCrfpMoc *self, return TRUE; } +/* Return the encryption status. This indicates if the seed and + * context have been set. + */ static gboolean crfpmoc_cmd_fp_enc_status (FpiDeviceCrfpMoc *self, guint32 *status, GError **error) @@ -882,14 +876,17 @@ crfpmoc_cmd_fp_enc_status (FpiDeviceCrfpMoc *self, struct crfpmoc_ec_response_fp_encryption_status resp = {0}; gboolean rv; - rv = crfpmoc_ec_command (self, CRFPMOC_EC_CMD_FP_ENC_STATUS, 0, NULL, 0, &resp, - sizeof (resp), error); + rv = crfpmoc_ec_command (self, CRFPMOC_EC_CMD_FP_ENC_STATUS, 0, + NULL, 0, + &resp, sizeof (resp), + error); if (rv != EC_RES_SUCCESS) return FALSE; fp_dbg ("crfpmoc_cmd_fp_enc_status: FPMCU encryption status: %d", resp.status); fp_dbg ("crfpmoc_cmd_fp_enc_status: valid flags: %d", resp.valid_flags); + // TODO: do we need to mask the status with valid_flags ? if (resp.status == CRFPMOC_FP_ENC_STATUS_SEED_SET) fp_dbg ("crfpmoc_cmd_fp_enc_status: seed is already set"); @@ -901,6 +898,8 @@ crfpmoc_cmd_fp_enc_status (FpiDeviceCrfpMoc *self, return TRUE; } +/* Set the device seed if it has not already been set. + */ static gboolean crfmoc_cmd_fp_ensure_seed (FpiDeviceCrfpMoc *self, const char *seed, GError **error) @@ -915,6 +914,7 @@ crfmoc_cmd_fp_ensure_seed (FpiDeviceCrfpMoc *self, fp_dbg ("crfmoc_cmd_fp_ensure_seed: FPMCU encryption status: %d", status); + // TODO: can there be other flags returned in the status ?? if (status == 0) { fp_dbg ("crfmoc_cmd_fp_ensure_seed: seed is not set, setting seed"); @@ -930,6 +930,8 @@ crfmoc_cmd_fp_ensure_seed (FpiDeviceCrfpMoc *self, return TRUE; } +/* Debug function to print the protocol infomation. + */ static void crfpmoc_show_proto_info (struct crfpmoc_ec_response_get_protocol_info *protocol_info) { @@ -942,16 +944,22 @@ crfpmoc_show_proto_info (struct crfpmoc_ec_response_get_protocol_info *protocol_ len += snprintf (&buffer[len], buflen - len, "%s%d", len == 0 ? "" : ",", i); buffer[buflen - 1] = '\0'; - fp_dbg ("crfpmoc_ec_max_outsize: vers %s, max_out %d, max_in %d, flags 0x%08x", + fp_dbg ("crfpmoc_show_proto_info: vers %s, max_out %d, max_in %d, flags 0x%08x", buffer, protocol_info->max_request_packet_size, protocol_info->max_response_packet_size, protocol_info->flags); } +/* Return the max in and out sizes from the protocol info request. It + * is assumed these values determine the size limits for commands. + */ +// Note: ectool uses a fixed smaller value either to work with older +// devices that do not support this request or some other reason. static gboolean -crfpmoc_ec_max_insize (FpiDeviceCrfpMoc *self, - guint16 *max_insize, GError **error) +crfpmoc_ec_max_size (FpiDeviceCrfpMoc *self, + guint16 *max_insize, guint16 *max_outsize, + GError **error) { struct crfpmoc_ec_response_get_protocol_info protocol_info; gboolean rv; @@ -962,32 +970,18 @@ crfpmoc_ec_max_insize (FpiDeviceCrfpMoc *self, return FALSE; crfpmoc_show_proto_info (&protocol_info); - *max_insize = protocol_info.max_response_packet_size - - sizeof (struct crfpmoc_ec_host_response); + if (max_insize) + *max_insize = protocol_info.max_response_packet_size - + sizeof (struct crfpmoc_ec_host_response); + if (max_outsize) + *max_outsize = protocol_info.max_request_packet_size - + sizeof (struct crfpmoc_ec_host_response); return TRUE; } -static gboolean -crfpmoc_ec_max_outsize (FpiDeviceCrfpMoc *self, - guint16 *max_outsize, GError **error) -{ - struct crfpmoc_ec_response_get_protocol_info protocol_info; - gboolean rv; - - rv = crfpmoc_ec_command (self, CRFPMOC_EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0, - &protocol_info, sizeof (protocol_info), error); - if (rv != EC_RES_SUCCESS) - return FALSE; - - crfpmoc_show_proto_info (&protocol_info); - *max_outsize = protocol_info.max_request_packet_size - - sizeof (struct crfpmoc_ec_host_request); - - return TRUE; -} - -/* Stolen BSD sum algorithm +/* Stolen BSD sum algorithm. Used for debug to allow matching the + * templates uploaded using ectool with the sum shell command. */ static uint16_t crfpmoc_sum (guint16 sum, guint8 * buffer, gsize len) @@ -1007,43 +1001,28 @@ crfpmoc_sum (guint16 sum, guint8 * buffer, gsize len) /* Download the last loaded template * * Issue the EC_CMD_FP_FRAME command to read the template. This is - * done in ec_max_insize chunks. The command will return EC_RES_BUSY + * done in max_insize chunks. The command will return EC_RES_BUSY * until the last chunk is read at which point it will return * EC_REC_SUCCESS. Any other response is considered an error. */ static gboolean crfpmoc_fp_download_template (FpiDeviceCrfpMoc *self, - struct crfpmoc_ec_response_fp_info *info, - gint index, guint8 **out_buffer, GError **error) + gint index, guint8 **out_buffer, + GError **error) { struct crfpmoc_ec_params_fp_template p; gsize stride, size; g_autofree guint8 *buffer = NULL; guint8 *ptr; gboolean rv; - gint cmdver = 1; - gsize rsize = sizeof (*info); const gint max_attempts = 3; gint num_attempts; - guint16 ec_max_insize; gint template_idx = index + CRFPMOC_FP_FRAME_INDEX_TEMPLATE; guint16 sum = 0; *out_buffer = NULL; - rv = crfpmoc_ec_max_insize (self, &ec_max_insize, error); - if (!rv) - return FALSE; - - rv = crfpmoc_ec_command (self, CRFPMOC_EC_CMD_FP_INFO, cmdver, NULL, 0, info, - rsize, error); - if (rv != EC_RES_SUCCESS) - { - fp_dbg ("crfpmoc_fp_download_template: failed to get info"); - return FALSE; - } - - size = info->template_size; + size = self->template_size; fp_dbg ("crfpmoc_fp_download_template: template size %zd", size); buffer = g_malloc0 (size); @@ -1051,6 +1030,7 @@ crfpmoc_fp_download_template (FpiDeviceCrfpMoc *self, p.offset = template_idx << CRFPMOC_FP_FRAME_INDEX_SHIFT; while (size > 0) { + // self->max_insize ?? stride = MIN (CRFPMOC_EC_PROTO2_MAX_PARAM_SIZE, size); p.size = stride; num_attempts = 0; @@ -1059,9 +1039,12 @@ crfpmoc_fp_download_template (FpiDeviceCrfpMoc *self, { num_attempts++; error = NULL; - fp_dbg ("crfpmoc_fp_download_template: read %zd bytes at %lu", stride, ptr - buffer); - rv = crfpmoc_ec_command (self, CRFPMOC_EC_CMD_FP_FRAME, 0, &p, sizeof (p), - ptr, stride, error); + fp_dbg ("crfpmoc_fp_download_template: read %zd bytes at %lu, off 0x%04x", + stride, ptr - buffer, p.offset); + rv = crfpmoc_ec_command (self, CRFPMOC_EC_CMD_FP_FRAME, + 0, &p, sizeof (p), + ptr, stride, + error); if (rv == EC_RES_SUCCESS) { fp_dbg ("crfpmoc_fp_download_template: frame done"); @@ -1097,11 +1080,12 @@ crfpmoc_fp_download_template (FpiDeviceCrfpMoc *self, return TRUE; } +/* Write a template to the device. This is done in max_outsize chunks. + */ static gboolean crfpmoc_fp_upload_template (FpiDeviceCrfpMoc *self, const guint8 *template_data, gsize template_size, - guint16 ec_max_outsize, GError **error) { struct crfpmoc_ec_params_fp_template *p = NULL; @@ -1112,6 +1096,7 @@ crfpmoc_fp_upload_template (FpiDeviceCrfpMoc *self, guint32 max_chunk; guint16 sum = 0; + // self->max_outsize ?? max_chunk = CRFPMOC_EC_PROTO2_MAX_PARAM_SIZE - offsetof (struct crfpmoc_ec_params_fp_template, data) - 4; @@ -1158,6 +1143,32 @@ crfpmoc_fp_upload_template (FpiDeviceCrfpMoc *self, return TRUE; } +/* State machine support functions + */ + +static void +crfpmoc_reset_device (FpDevice *device) +{ + FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); + + fp_dbg ("crfpmoc_reset_device"); + + /* Cancel the running state machine, if any */ + if (self->task_ssm != NULL) + fpi_ssm_mark_failed (self->task_ssm, + g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "Cancelled")); + + /* Issue reset */ + crfpmoc_cmd_fp_mode (self, 0, NULL, NULL); + + g_cancellable_cancel (self->interrupt_cancellable); + g_clear_object (&self->interrupt_cancellable); + self->interrupt_cancellable = g_cancellable_new (); +} + +/* Enable event reporting for fingerprint events and queue up a + * callback to read the next event. + */ static void crfpmoc_cmd_wait_event_fingerprint (FpiSsm *ssm) { @@ -1166,7 +1177,12 @@ crfpmoc_cmd_wait_event_fingerprint (FpiSsm *ssm) crfpmoc_ec_pollevent (ssm, 1 << event_type); } -/* Generic task completion callback to report any errors +/* State machines + */ + +/* Generic task completion callback to report any errors. Only to be + * used for top level tasks since it assumes it is completing + * self->task_ssm. */ static void crfpmoc_task_ssm_done (FpiSsm *ssm, FpDevice *device, @@ -1183,50 +1199,22 @@ crfpmoc_task_ssm_done (FpiSsm *ssm, FpDevice *device, } static void -crfpmoc_open (FpDevice *device) +crfpmoc_wait_for_device_idle (FpiSsm *ssm, FpDevice *device) { FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); - GError *err = NULL; - const char *file = - fpi_device_get_udev_data (FP_DEVICE (device), FPI_DEVICE_UDEV_SUBTYPE_MISC); + guint mode; + GError *error = NULL; - fp_dbg ("Opening device %s", file); - - self->interrupt_cancellable = g_cancellable_new (); - - int fd = open (file, O_RDWR); - - if (fd < 0) - { - g_set_error (&err, G_IO_ERROR, g_io_error_from_errno (errno), - "unable to open misc device"); - fp_dbg ("crfpmoc_open: open_complete"); - fpi_device_open_complete (device, err); - return; - } - - self->fd = fd; - - /* For testing we need to create the umockdev trace file ourselves - * since there is no record support. There is playback support. - */ - if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0) - self->emul_fd = creat ("/tmp/crfpmoc.ioctl", 0777); - - /* Just for debug messages */ - guint16 ec_max_outsize; - if (!crfpmoc_ec_max_outsize (self, &ec_max_outsize, &err)) - fp_err ("Failed to get max outsize"); - - /* Just for debug messages */ - guint16 ec_max_insize; - if (!crfpmoc_ec_max_insize (self, &ec_max_insize, &err)) - fp_err ("Failed to get max insize"); - - fp_dbg ("crfpmoc_open: open_complete"); - fpi_device_open_complete (device, NULL); + if (!crfpmoc_cmd_fp_mode (self, CRFPMOC_FP_MODE_DONT_CHANGE, &mode, &error)) + fpi_ssm_mark_failed (ssm, error); + else if (mode == 0) + fpi_ssm_next_state (ssm); + else + fpi_ssm_jump_to_state_delayed (ssm, fpi_ssm_get_cur_state (ssm), 100); } +/* Convenience routine to make sure the seed and context are set + */ static gboolean crfpmoc_set_keys (FpiDeviceCrfpMoc *self, GError **error) { @@ -1243,88 +1231,6 @@ crfpmoc_set_keys (FpiDeviceCrfpMoc *self, GError **error) return TRUE; } -static void -crfpmoc_cancel (FpDevice *device) -{ - fp_dbg ("Cancel"); - FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); - - /* Cancel the running state machine, if any */ - if (self->task_ssm != NULL) - fpi_ssm_mark_failed (self->task_ssm, - g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "Cancelled")); - - /* Issue reset */ - crfpmoc_cmd_fp_mode (self, 0, NULL, NULL); - - g_cancellable_cancel (self->interrupt_cancellable); - g_clear_object (&self->interrupt_cancellable); - self->interrupt_cancellable = g_cancellable_new (); -} - -static void -crfpmoc_suspend (FpDevice *device) -{ - fp_dbg ("Suspend"); - - crfpmoc_cancel (device); - g_cancellable_cancel (fpi_device_get_cancellable (device)); - fp_dbg ("crfpmoc_suspend: suspend_complete"); - fpi_device_suspend_complete (device, NULL); -} - -static void -crfpmoc_close (FpDevice *device) -{ - fp_dbg ("Closing device"); - FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); - - crfpmoc_cancel (device); - g_clear_object (&self->interrupt_cancellable); - - if (self->fd >= 0) - { - close (self->fd); - self->fd = -1; - } - if (self->emul_fd >= 0) - { - close (self->emul_fd); - self->emul_fd = -1; - } - fp_dbg ("crfpmoc_close: close_complete"); - fpi_device_close_complete (device, NULL); -} - -static void -handle_enroll_sensor_enroll (FpiSsm *ssm, FpiDeviceCrfpMoc *self) -{ - GError *error = NULL; - guint32 mode; - gboolean r = crfpmoc_cmd_fp_mode (self, - CRFPMOC_FP_MODE_ENROLL_IMAGE | - CRFPMOC_FP_MODE_ENROLL_SESSION, - &mode, &error); - - if (!r) - fpi_ssm_mark_failed (ssm, error); - else - fpi_ssm_next_state (ssm); -} - -static void -handle_enroll_wait_enroll_complete (FpDevice *device, - FpiDeviceCrfpMoc *self) -{ - - /* Sensor awaits the finger down - */ - fpi_device_report_finger_status_changes (device, - FP_FINGER_STATUS_NEEDED, - FP_FINGER_STATUS_NONE); - crfpmoc_cmd_wait_event_fingerprint (self->task_ssm); -} - static gint crfpmoc_ssm_timeout (gpointer user_data) { @@ -1380,6 +1286,120 @@ handle_xxx_wait_finger_up (FpDevice *device, crfpmoc_cmd_wait_event_fingerprint (ssm); } +/* Clear storage state machine + */ + +static void +crfpmoc_clear_storage_run_state (FpiSsm *ssm, FpDevice *device) +{ + FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); + gboolean r; + guint32 mode; + GError *error = NULL; + int state = fpi_ssm_get_cur_state (ssm); + + switch (state) + { + case CLEAR_STORAGE_SENSOR_RESET: + fp_dbg ("crfpmoc_clear_storage_run_state: reset"); + /* Start with a reset just in case */ + r = crfpmoc_cmd_fp_mode (self, 0, &mode, &error); + if (!r) + { + fpi_ssm_mark_failed (ssm, error); + } + else + { + fp_dbg ("crfpmoc_clear_storage_run_state: reset sensor"); + r = crfpmoc_cmd_fp_mode (self, CRFPMOC_FP_MODE_RESET_SENSOR, &mode, &error); + if (!r) + fpi_ssm_mark_failed (ssm, error); + else + fpi_ssm_next_state (ssm); + } + break; + + case CLEAR_STORAGE_SENSOR_WAIT: + crfpmoc_wait_for_device_idle (ssm, device); + break; + + case CLEAR_STORAGE_SENSOR_DONE: + if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_CLEAR_STORAGE) + { + fp_dbg ("crfpmoc_clear_storage_run_state: clear_storage_complete"); + fpi_device_clear_storage_complete (device, NULL); + } + fpi_ssm_mark_completed (ssm); + break; + } + fp_dbg ("crfpmoc_clear_storage_run_state: state %d return", + state); +} + +/* Finger up state machine + */ + +static void +crfpmoc_finger_up_run_state (FpiSsm *ssm, FpDevice *device) +{ + FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); + int state = fpi_ssm_get_cur_state (ssm); + + switch (state) + { + case FINGER_UP_START: /* State 0 */ + handle_xxx_wait_finger_up (device, self, ssm, + FINGER_UP_TIMEOUT, + 5000); + break; + + case FINGER_UP_DONE: /* State 1 */ + fpi_ssm_mark_completed (ssm); + break; + + /* User has not lifted finger. Send a retry error to prompt them + */ + case FINGER_UP_TIMEOUT: /* State 2 */ + fpi_ssm_mark_failed (ssm, + fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER)); + break; + } + fp_dbg ("crfpmoc_finger_up_run_state: state %d return", + state); +} + +/* Enroll state machine + */ + +static void +handle_enroll_sensor_enroll (FpiSsm *ssm, FpiDeviceCrfpMoc *self) +{ + GError *error = NULL; + guint32 mode; + gboolean r = crfpmoc_cmd_fp_mode (self, + CRFPMOC_FP_MODE_ENROLL_IMAGE | + CRFPMOC_FP_MODE_ENROLL_SESSION, + &mode, &error); + + if (!r) + fpi_ssm_mark_failed (ssm, error); + else + fpi_ssm_next_state (ssm); +} + +static void +handle_enroll_wait_enroll_complete (FpDevice *device, + FpiDeviceCrfpMoc *self) +{ + + /* Sensor awaits the finger down + */ + fpi_device_report_finger_status_changes (device, + FP_FINGER_STATUS_NEEDED, + FP_FINGER_STATUS_NONE); + crfpmoc_cmd_wait_event_fingerprint (self->task_ssm); +} + static void handle_enroll_sensor_check (FpiSsm *ssm, FpDevice *device, FpiDeviceCrfpMoc *self, @@ -1449,10 +1469,8 @@ handle_enroll_commit (FpiSsm *ssm, FpDevice *device, GError *error = NULL; guint16 enrolled_templates = 0; g_autofree guint8 *template = NULL; - guint16 ec_max_outsize = 10; - struct crfpmoc_ec_response_fp_info info; - crfpmoc_cmd_fp_info (self, &enrolled_templates, &error); + crfpmoc_cmd_fp_info (self, &enrolled_templates, NULL, NULL, &error); fp_dbg ("Number of enrolled templates is: %d", enrolled_templates); g_autofree gchar *user_id = fpi_print_generate_user_id (enroll_data->print); @@ -1460,28 +1478,13 @@ handle_enroll_commit (FpiSsm *ssm, FpDevice *device, g_object_set (enroll_data->print, "description", user_id, NULL); - gboolean r = crfpmoc_ec_max_outsize (self, &ec_max_outsize, &error); - if (!r) - { - fp_err ("Failed to get max outsize"); - crfpmoc_set_print_data (enroll_data->print, enrolled_templates - 1, - NULL, 0, - ec_max_outsize, info.template_max); - fpi_ssm_mark_failed (ssm, - fpi_device_retry_new_msg (FP_DEVICE_RETRY_GENERAL, - "Failed to get max outsize")); - return; - } - - - r = crfpmoc_fp_download_template (self, &info, enrolled_templates - 1, - &template, &error); + gboolean r = crfpmoc_fp_download_template (self, enrolled_templates - 1, + &template, &error); if (!r) { fp_err ("Failed to download template"); - crfpmoc_set_print_data (enroll_data->print, enrolled_templates - 1, NULL, 0, - ec_max_outsize, info.template_max); + crfpmoc_set_print_data (enroll_data->print, enrolled_templates - 1, NULL, 0); fpi_ssm_mark_failed (ssm, fpi_device_retry_new_msg (FP_DEVICE_RETRY_GENERAL, "Failed to download template")); @@ -1489,8 +1492,7 @@ handle_enroll_commit (FpiSsm *ssm, FpDevice *device, else { crfpmoc_set_print_data (enroll_data->print, enrolled_templates - 1, - template, info.template_size, ec_max_outsize, - info.template_max); + template, self->template_size); } fp_info ("handle_enroll_commit: enroll_complete"); @@ -1540,33 +1542,39 @@ crfpmoc_enroll_run_state (FpiSsm *ssm, FpDevice *device) state); } +/* Verify/Identify state machine + */ + static void -crfpmoc_enroll (FpDevice *device) +handle_verify_clear_storage (FpiSsm *ssm, FpDevice *device, + FpiDeviceCrfpMoc *self) +{ + FpiSsm *sub = fpi_ssm_new (device, crfpmoc_clear_storage_run_state, + CLEAR_STORAGE_STATES); + + crfpmoc_ssm_start_subsm (self->task_ssm, sub, self, NULL); +} + +static void +handle_verify_finger_up (FpiSsm *ssm, FpDevice *device, + FpiDeviceCrfpMoc *self) +{ + FpiSsm *sub = fpi_ssm_new (device, crfpmoc_finger_up_run_state, + FINGER_UP_STATES); + + crfpmoc_ssm_start_subsm (self->task_ssm, sub, self, NULL); +} + +static void +handle_verify_set_seed (FpiSsm *ssm, FpDevice *device, + FpiDeviceCrfpMoc *self) { - fp_dbg ("Enroll"); GError *error = NULL; - gboolean r; - FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); - struct crfpmoc_enroll_data *enroll_data = - g_malloc0 (sizeof (struct crfpmoc_enroll_data)); - r = crfpmoc_set_keys (self, &error); - if (!r) - { - fp_dbg ("crfpmoc_enroll: enroll_complete"); - fpi_device_enroll_complete (device, NULL, error); - return; - } - - fpi_device_get_enroll_data (device, &enroll_data->print); - enroll_data->stage = 0; - - g_assert (self->task_ssm == NULL); - self->task_ssm = - fpi_ssm_new (device, crfpmoc_enroll_run_state, ENROLL_STATES); - crfpmoc_ssm_start (self->task_ssm, self, - (struct crfpmoc_ssm_data *) enroll_data, - crfpmoc_task_ssm_done); + if (!crfpmoc_set_keys (self, &error)) + fpi_ssm_mark_failed (ssm, error); + else + fpi_ssm_next_state (ssm); } static void @@ -1575,8 +1583,6 @@ handle_verify_upload_template (FpiSsm *ssm, FpDevice *device, { GError *error = NULL; gboolean upload_successful = FALSE; - guint16 fp_ec_max_outsize = 10; - guint16 fp_max_templates = 10; g_autofree guint8 *template = NULL; size_t template_size = 0; FpPrint *print = NULL; @@ -1591,24 +1597,15 @@ handle_verify_upload_template (FpiSsm *ssm, FpDevice *device, if (prints && prints->len > 0) { - for (guint index = 0; index < prints->len && index < fp_max_templates; + for (guint index = 0; index < prints->len && index < self->max_templates; index++) { print = g_ptr_array_index (prints, index); - crfpmoc_get_print_data (print, &template, &template_size, - &fp_ec_max_outsize, &fp_max_templates); - - if (!fp_ec_max_outsize) - { - crfpmoc_ec_max_outsize (self, &fp_ec_max_outsize, &error); - fp_warn ("Max outsize is not set, getting it from the device"); - // TODO: If this issue can't be fixed, we should only get the max - // outsize once and use it for all templates. - } + crfpmoc_get_print_data (print, &template, &template_size); if (crfpmoc_fp_upload_template (self, template, template_size, - fp_ec_max_outsize, &error)) + &error)) { fp_dbg ("uploaded template, %zd bytes", template_size); upload_successful = TRUE; @@ -1629,18 +1626,11 @@ handle_verify_upload_template (FpiSsm *ssm, FpDevice *device, if (print) { - crfpmoc_get_print_data (print, &template, &template_size, - &fp_ec_max_outsize, &fp_max_templates); - - if (!fp_ec_max_outsize) - { - crfpmoc_ec_max_outsize (self, &fp_ec_max_outsize, &error); - fp_warn ("Max outsize is not set, getting it from the device"); - } + crfpmoc_get_print_data (print, &template, &template_size); upload_successful = crfpmoc_fp_upload_template (self, template, template_size, - fp_ec_max_outsize, &error); + &error); if (!upload_successful) { fp_warn ("Failed to upload template: %s", @@ -1786,7 +1776,7 @@ handle_verify_check (FpiSsm *ssm, FpDevice *device, FpPrint *print = NULL; guint16 enrolled_templates = 0; - if (!crfpmoc_cmd_fp_info (self, &enrolled_templates, &error)) + if (!crfpmoc_cmd_fp_info (self, &enrolled_templates, NULL, NULL, &error)) { fp_dbg ("handle_verify_check: no info"); fpi_ssm_mark_failed (ssm, error); @@ -1853,129 +1843,6 @@ handle_verify_check (FpiSsm *ssm, FpDevice *device, fpi_ssm_mark_completed (ssm); } -static void -crfpmoc_cmd_wait_for_it (FpiSsm *ssm, FpDevice *device) -{ - FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); - guint mode; - GError *error = NULL; - - if (!crfpmoc_cmd_fp_mode (self, CRFPMOC_FP_MODE_DONT_CHANGE, &mode, &error)) - fpi_ssm_mark_failed (ssm, error); - else if (mode == 0) - fpi_ssm_next_state (ssm); - else - fpi_ssm_jump_to_state_delayed (ssm, fpi_ssm_get_cur_state (ssm), 100); -} - -static void -crfpmoc_finger_up_run_state (FpiSsm *ssm, FpDevice *device) -{ - FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); - int state = fpi_ssm_get_cur_state (ssm); - - switch (state) - { - case FINGER_UP_START: /* State 0 */ - handle_xxx_wait_finger_up (device, self, ssm, - FINGER_UP_TIMEOUT, - 5000); - break; - - case FINGER_UP_DONE: /* State 1 */ - fpi_ssm_mark_completed (ssm); - break; - - /* User has not lifted finger. Send a retry error to prompt them - */ - case FINGER_UP_TIMEOUT: /* State 2 */ - fpi_ssm_mark_failed (ssm, - fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER)); - break; - } - fp_dbg ("crfpmoc_finger_up_run_state: state %d return", - state); -} - -static void -handle_verify_finger_up (FpiSsm *ssm, FpDevice *device, - FpiDeviceCrfpMoc *self) -{ - FpiSsm *sub = fpi_ssm_new (device, crfpmoc_finger_up_run_state, - FINGER_UP_STATES); - - crfpmoc_ssm_start_subsm (self->task_ssm, sub, self, NULL); -} - -static void -crfpmoc_clear_storage_run_state (FpiSsm *ssm, FpDevice *device) -{ - FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); - gboolean r; - guint32 mode; - GError *error = NULL; - int state = fpi_ssm_get_cur_state (ssm); - - switch (state) - { - case CLEAR_STORAGE_SENSOR_RESET: - fp_dbg ("crfpmoc_clear_storage_run_state: reset"); - /* Start with a reset just in case */ - r = crfpmoc_cmd_fp_mode (self, 0, &mode, &error); - if (!r) - { - fpi_ssm_mark_failed (ssm, error); - } - else - { - fp_dbg ("crfpmoc_clear_storage_run_state: reset sensor"); - r = crfpmoc_cmd_fp_mode (self, CRFPMOC_FP_MODE_RESET_SENSOR, &mode, &error); - if (!r) - fpi_ssm_mark_failed (ssm, error); - else - fpi_ssm_next_state (ssm); - } - break; - - case CLEAR_STORAGE_SENSOR_WAIT: - crfpmoc_cmd_wait_for_it (ssm, device); - break; - - case CLEAR_STORAGE_SENSOR_DONE: - if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_CLEAR_STORAGE) - { - fp_dbg ("crfpmoc_clear_storage_run_state: clear_storage_complete"); - fpi_device_clear_storage_complete (device, NULL); - } - fpi_ssm_mark_completed (ssm); - break; - } - fp_dbg ("crfpmoc_clear_storage_run_state: state %d return", - state); -} - -static void -handle_verify_clear_storage (FpiSsm *ssm, FpDevice *device, - FpiDeviceCrfpMoc *self) -{ - FpiSsm *sub = fpi_ssm_new (device, crfpmoc_clear_storage_run_state, - CLEAR_STORAGE_STATES); - - crfpmoc_ssm_start_subsm (self->task_ssm, sub, self, NULL); -} - -static void -handle_verify_set_seed (FpiSsm *ssm, FpDevice *device, - FpiDeviceCrfpMoc *self) -{ - GError *error = NULL; - - if (!crfpmoc_set_keys (self, &error)) - fpi_ssm_mark_failed (ssm, error); - else - fpi_ssm_next_state (ssm); -} - static void crfpmoc_verify_run_state (FpiSsm *ssm, FpDevice *device) { @@ -2070,9 +1937,111 @@ crfpmoc_verify_ssm_done (FpiSsm *ssm, FpDevice *device, fpi_device_identify_complete (device, error); } } - crfpmoc_cancel (device); + crfpmoc_reset_device (device); } +/* Device request handlers + */ + +/* Handle the open device request. + */ +static void +crfpmoc_open (FpDevice *device) +{ + FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); + GError *err = NULL; + const char *file = + fpi_device_get_udev_data (FP_DEVICE (device), FPI_DEVICE_UDEV_SUBTYPE_MISC); + + fp_dbg ("Opening device %s", file); + + self->interrupt_cancellable = g_cancellable_new (); + + int fd = open (file, O_RDWR); + + if (fd < 0) + { + g_set_error (&err, G_IO_ERROR, g_io_error_from_errno (errno), + "unable to open misc device"); + fp_dbg ("crfpmoc_open: open_complete"); + fpi_device_open_complete (device, err); + return; + } + + self->fd = fd; + + /* For testing we need to create the umockdev trace file ourselves + * since there is no record support. There is playback support. + */ + if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0) + self->emul_fd = creat ("/tmp/crfpmoc.ioctl", 0777); + + if (!crfpmoc_ec_max_size (self, &self->max_insize, &self->max_outsize, &err)) + fp_err ("Failed to get max insize/outsize"); + else if (!crfpmoc_cmd_fp_info (self, + NULL, + &self->max_templates, + &self->template_size, + &err)) + fp_err ("Failed to get max insize/outsize"); + + fp_dbg ("crfpmoc_open: open_complete"); + fpi_device_open_complete (device, err); +} + +/* Handle the device cancel request. + */ +static void +crfpmoc_cancel (FpDevice *device) +{ + fp_dbg ("Cancel"); + + crfpmoc_reset_device (device); +} + +/* Handle the device suspend request. + */ +static void +crfpmoc_suspend (FpDevice *device) +{ + fp_dbg ("Suspend"); + + crfpmoc_reset_device (device); + + g_cancellable_cancel (fpi_device_get_cancellable (device)); + fp_dbg ("crfpmoc_suspend: suspend_complete"); + fpi_device_suspend_complete (device, NULL); +} + +/* Handle the device close request. + */ +static void +crfpmoc_close (FpDevice *device) +{ + fp_dbg ("Closing device"); + FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); + + crfpmoc_reset_device (device); + g_clear_object (&self->interrupt_cancellable); + + if (self->fd >= 0) + { + close (self->fd); + self->fd = -1; + } + if (self->emul_fd >= 0) + { + close (self->emul_fd); + self->emul_fd = -1; + } + fp_dbg ("crfpmoc_close: close_complete"); + fpi_device_close_complete (device, NULL); +} + +/* Handle device verify or identify requests. These are very similar + * only differing in request prints and report formats. The procedure + * for each is identical. + */ static void crfpmoc_identify_verify (FpDevice *device) { @@ -2085,6 +2054,39 @@ crfpmoc_identify_verify (FpDevice *device) crfpmoc_ssm_start (self->task_ssm, self, NULL, crfpmoc_verify_ssm_done); } +/* Handle device enroll request. + */ +static void +crfpmoc_enroll (FpDevice *device) +{ + fp_dbg ("Enroll"); + GError *error = NULL; + gboolean r; + FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device); + struct crfpmoc_enroll_data *enroll_data = + g_malloc0 (sizeof (struct crfpmoc_enroll_data)); + + r = crfpmoc_set_keys (self, &error); + if (!r) + { + fp_dbg ("crfpmoc_enroll: enroll_complete"); + fpi_device_enroll_complete (device, NULL, error); + return; + } + + fpi_device_get_enroll_data (device, &enroll_data->print); + enroll_data->stage = 0; + + g_assert (self->task_ssm == NULL); + self->task_ssm = + fpi_ssm_new (device, crfpmoc_enroll_run_state, ENROLL_STATES); + crfpmoc_ssm_start (self->task_ssm, self, + (struct crfpmoc_ssm_data *) enroll_data, + crfpmoc_task_ssm_done); +} + +/* Handle device clear storage request. + */ static void crfpmoc_clear_storage (FpDevice *device) { @@ -2097,13 +2099,20 @@ crfpmoc_clear_storage (FpDevice *device) crfpmoc_ssm_start (self->task_ssm, self, NULL, crfpmoc_task_ssm_done); } +/* Handle device initialization. Called before any other device op. + */ static void fpi_device_crfpmoc_init (FpiDeviceCrfpMoc *self) { + memset (&self->task_ssm, 0, + sizeof (*self) - offsetof (FpiDeviceCrfpMoc, task_ssm)); self->fd = -1; self->emul_fd = -1; } +/* Register the device. Note, this function is declared in the + * G_DEFINE_TYPE macro and registered there. + */ static void fpi_device_crfpmoc_class_init (FpiDeviceCrfpMocClass *klass) { @@ -2121,6 +2130,7 @@ fpi_device_crfpmoc_class_init (FpiDeviceCrfpMocClass *klass) dev_class->open = crfpmoc_open; dev_class->cancel = crfpmoc_cancel; dev_class->suspend = crfpmoc_suspend; + // TODO: suspend but no resume ?? do we need either ? dev_class->close = crfpmoc_close; dev_class->enroll = crfpmoc_enroll; dev_class->identify = crfpmoc_identify_verify; diff --git a/tests/crfpmoc/custom.ioctl b/tests/crfpmoc/custom.ioctl index b0d3428a..688b6f2a 100644 --- a/tests/crfpmoc/custom.ioctl +++ b/tests/crfpmoc/custom.ioctl @@ -1,6 +1,6 @@ @DEV /dev/cros_fp CROS_EC_DEV_IOCXCMD_V2 12 000000000B000000000000000C00000000000000080000002002200201000000 -CROS_EC_DEV_IOCXCMD_V2 12 000000000B000000000000000C00000000000000080000002002200201000000 +CROS_EC_DEV_IOCXCMD_V2 48 010000000304000000000000300000000000000046504320090000001F020000010000009466000047524559A000A0000800FF0324140000050001000100000004000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000080000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000080000000 @@ -21,9 +21,6 @@ CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000010000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000030000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 48 010000000304000000000000300000000000000046504320090000001F020000010000009466000047524559A000A0000800FF0324140000050001000100000004000000 -CROS_EC_DEV_IOCXCMD_V2 12 000000000B000000000000000C00000000000000080000002002200201000000 -CROS_EC_DEV_IOCXCMD_V2 12 000000000B000000000000000C00000000000000080000002002200201000000 -CROS_EC_DEV_IOCXCMD_V2 48 010000000304000000000000300000000000000046504320090000001F020000010000009466000047524559A000A0000800FF0324140000050001000100000004000000 CROS_EC_DEV_IOCXCMD_V2 252 000000000404000008000000FC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 252 000000000404000008000000FC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 252 000000000404000008000000FC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -80,7 +77,7 @@ CROS_EC_DEV_IOCXCMD_V2 0 00000000050400007C0000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000040000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 48 010000000304000000000000300000000000000046504320090000001F020000010000009466000047524559A000A0000800FF0324140000050001000100000004000000 -CROS_EC_DEV_IOCXCMD_V2 22 00000000070400000000000016000000000000002471010098C40200D03A0400E81B920D4D0000000000 +CROS_EC_DEV_IOCXCMD_V2 22 00000000070400000000000016000000000000002471010064D50200004C0400ECEBAD23600000000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000080000000 @@ -117,7 +114,7 @@ CROS_EC_DEV_IOCXCMD_V2 0 00000000050400007C0000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000040000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 48 010000000304000000000000300000000000000046504320090000001F020000010000009466000047524559A000A0000800FF0324140000050001000100000004000000 -CROS_EC_DEV_IOCXCMD_V2 22 00000000070400000000000016000000000000002471010078C10200783804007C52A90D4D0000000000 +CROS_EC_DEV_IOCXCMD_V2 22 00000000070400000000000016000000000000002471010018D102005047040030ABC823600000000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000000000000 CROS_EC_DEV_IOCXCMD_V2 4 000000000204000004000000040000000000000080000000 diff --git a/tests/crfpmoc/device b/tests/crfpmoc/device index a226e6bf..15524ac1 100644 --- a/tests/crfpmoc/device +++ b/tests/crfpmoc/device @@ -52,39 +52,39 @@ A: power/runtime_usage=0\n A: power/wakeup=enabled\n A: power/wakeup_abort_count=0\n A: power/wakeup_active=0\n -A: power/wakeup_active_count=1742\n +A: power/wakeup_active_count=1779\n A: power/wakeup_count=0\n A: power/wakeup_expire_count=0\n -A: power/wakeup_last_time_ms=288328363\n +A: power/wakeup_last_time_ms=370430567\n A: power/wakeup_max_time_ms=0\n A: power/wakeup_total_time_ms=0\n -A: statistics/bytes=7992753\n -A: statistics/bytes_rx=7992753\n -A: statistics/bytes_tx=1847815\n +A: statistics/bytes=8559778\n +A: statistics/bytes_rx=8559778\n +A: statistics/bytes_tx=2021451\n A: statistics/errors=0\n -A: statistics/messages=275116\n +A: statistics/messages=304844\n A: statistics/spi_async=0\n -A: statistics/spi_sync=275116\n -A: statistics/spi_sync_immediate=275116\n +A: statistics/spi_sync=304844\n +A: statistics/spi_sync_immediate=304844\n A: statistics/timedout=0\n -A: statistics/transfer_bytes_histo_0-1=52216\n +A: statistics/transfer_bytes_histo_0-1=60993\n A: statistics/transfer_bytes_histo_1024-2047=0\n -A: statistics/transfer_bytes_histo_128-255=1468\n -A: statistics/transfer_bytes_histo_16-31=2867\n +A: statistics/transfer_bytes_histo_128-255=1510\n +A: statistics/transfer_bytes_histo_16-31=2901\n A: statistics/transfer_bytes_histo_16384-32767=0\n -A: statistics/transfer_bytes_histo_2-3=852\n +A: statistics/transfer_bytes_histo_2-3=862\n A: statistics/transfer_bytes_histo_2048-4095=0\n -A: statistics/transfer_bytes_histo_256-511=5797\n -A: statistics/transfer_bytes_histo_32-63=163370\n +A: statistics/transfer_bytes_histo_256-511=6196\n +A: statistics/transfer_bytes_histo_32-63=175509\n A: statistics/transfer_bytes_histo_32768-65535=0\n -A: statistics/transfer_bytes_histo_4-7=2016\n +A: statistics/transfer_bytes_histo_4-7=2039\n A: statistics/transfer_bytes_histo_4096-8191=0\n A: statistics/transfer_bytes_histo_512-1023=711\n -A: statistics/transfer_bytes_histo_64-127=759\n +A: statistics/transfer_bytes_histo_64-127=760\n A: statistics/transfer_bytes_histo_65536+=0\n -A: statistics/transfer_bytes_histo_8-15=45060\n +A: statistics/transfer_bytes_histo_8-15=53363\n A: statistics/transfer_bytes_histo_8192-16383=0\n -A: statistics/transfers=275116\n +A: statistics/transfers=304844\n A: statistics/transfers_split_maxsize=0\n P: /devices/pci0000:00/0000:00:1e.3/pxa2xx-spi.8/spi_master/spi1 @@ -100,33 +100,33 @@ A: power/runtime_status=unsupported\n A: power/runtime_suspended_time=0\n A: power/runtime_usage=0\n L: software_node=../../../../../../kernel/software_nodes/node3 -A: statistics/bytes=7992753\n -A: statistics/bytes_rx=7992753\n -A: statistics/bytes_tx=1847815\n +A: statistics/bytes=8559778\n +A: statistics/bytes_rx=8559778\n +A: statistics/bytes_tx=2021451\n A: statistics/errors=0\n -A: statistics/messages=275116\n +A: statistics/messages=304844\n A: statistics/spi_async=0\n -A: statistics/spi_sync=275116\n -A: statistics/spi_sync_immediate=275116\n +A: statistics/spi_sync=304844\n +A: statistics/spi_sync_immediate=304844\n A: statistics/timedout=0\n -A: statistics/transfer_bytes_histo_0-1=52216\n +A: statistics/transfer_bytes_histo_0-1=60993\n A: statistics/transfer_bytes_histo_1024-2047=0\n -A: statistics/transfer_bytes_histo_128-255=1468\n -A: statistics/transfer_bytes_histo_16-31=2867\n +A: statistics/transfer_bytes_histo_128-255=1510\n +A: statistics/transfer_bytes_histo_16-31=2901\n A: statistics/transfer_bytes_histo_16384-32767=0\n -A: statistics/transfer_bytes_histo_2-3=852\n +A: statistics/transfer_bytes_histo_2-3=862\n A: statistics/transfer_bytes_histo_2048-4095=0\n -A: statistics/transfer_bytes_histo_256-511=5797\n -A: statistics/transfer_bytes_histo_32-63=163370\n +A: statistics/transfer_bytes_histo_256-511=6196\n +A: statistics/transfer_bytes_histo_32-63=175509\n A: statistics/transfer_bytes_histo_32768-65535=0\n -A: statistics/transfer_bytes_histo_4-7=2016\n +A: statistics/transfer_bytes_histo_4-7=2039\n A: statistics/transfer_bytes_histo_4096-8191=0\n A: statistics/transfer_bytes_histo_512-1023=711\n -A: statistics/transfer_bytes_histo_64-127=759\n +A: statistics/transfer_bytes_histo_64-127=760\n A: statistics/transfer_bytes_histo_65536+=0\n -A: statistics/transfer_bytes_histo_8-15=45060\n +A: statistics/transfer_bytes_histo_8-15=53363\n A: statistics/transfer_bytes_histo_8192-16383=0\n -A: statistics/transfers=275116\n +A: statistics/transfers=304844\n A: statistics/transfers_split_maxsize=0\n A: waiting_for_supplier=0\n @@ -145,10 +145,10 @@ A: power/async=disabled\n A: power/autosuspend_delay_ms=50\n A: power/control=auto\n A: power/runtime_active_kids=0\n -A: power/runtime_active_time=2111536\n +A: power/runtime_active_time=2600804\n A: power/runtime_enabled=enabled\n A: power/runtime_status=suspended\n -A: power/runtime_suspended_time=286222682\n +A: power/runtime_suspended_time=368046223\n A: power/runtime_usage=0\n L: software_node=../../../../kernel/software_nodes/node3 @@ -191,10 +191,10 @@ A: power/async=enabled\n A: power/control=auto\n A: power/pm_qos_latency_tolerance_us=auto\n A: power/runtime_active_kids=0\n -A: power/runtime_active_time=2944140\n +A: power/runtime_active_time=3636822\n A: power/runtime_enabled=enabled\n A: power/runtime_status=suspended\n -A: power/runtime_suspended_time=285393064\n +A: power/runtime_suspended_time=367013193\n A: power/runtime_usage=0\n A: power_state=D3hot\n A: resource=0x000000007ff55000 0x000000007ff55fff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n