Compare commits

..
Author SHA1 Message Date
Matthew Mirvish b50cba1fa4 fixup! elanspi: preliminary support for 04f3:3104 2022-05-23 13:16:21 -04:00
Matthew Mirvish 46591d7bfa elanspi: preliminary support for 04f3:3104
Also adds "quirk" flags to driver_data so other special case things
can be handled with less effort going forwards.
2022-05-03 21:02:26 -04:00
13 changed files with 475 additions and 408 deletions
+45 -18
View File
@@ -63,6 +63,7 @@ struct _FpiDeviceElanSpi
guint16 gdac_step; guint16 gdac_step;
guint16 best_gdac; guint16 best_gdac;
guint16 best_meandiff; guint16 best_meandiff;
guint16 target_mean;
} hv_data; } hv_data;
}; };
@@ -408,6 +409,10 @@ elanspi_determine_sensor (FpiDeviceElanSpi *self, GError **err)
self->frame_width = self->sensor_width; self->frame_width = self->sensor_width;
self->frame_height = self->sensor_height > ELANSPI_MAX_FRAME_HEIGHT ? ELANSPI_MAX_FRAME_HEIGHT : self->sensor_height; self->frame_height = self->sensor_height > ELANSPI_MAX_FRAME_HEIGHT ? ELANSPI_MAX_FRAME_HEIGHT : self->sensor_height;
} }
/* check x571 flag */
if (self->sensor_id == 0xe)
self->hv_data.target_mean = (fpi_device_get_driver_data (FP_DEVICE (self)) & ELANSPI_QUIRK_X571 ? ELANSPI_HV_X571_CALIBRATION_TARGET_MEAN : ELANSPI_HV_CALIBRATION_TARGET_MEAN);
} }
static void static void
@@ -542,7 +547,7 @@ elanspi_write_regtable (FpiDeviceElanSpi *self, const struct elanspi_regtable *
for (int i = 0; table->entries[i].table; i += 1) for (int i = 0; table->entries[i].table; i += 1)
{ {
if (table->entries[i].sid == self->sensor_id) if (table->entries[i].sid == self->sensor_id && table->entries[i].quirk == (fpi_device_get_driver_data (FP_DEVICE (self)) & ELANSPI_QUIRK_MASK))
{ {
starting_entry = table->entries[i].table; starting_entry = table->entries[i].table;
break; break;
@@ -692,6 +697,8 @@ static void
elanspi_capture_hv_image_handler (FpiSpiTransfer *transfer, FpDevice *dev, gpointer unused_data, GError *error) elanspi_capture_hv_image_handler (FpiSpiTransfer *transfer, FpDevice *dev, gpointer unused_data, GError *error)
{ {
FpiDeviceElanSpi *self = FPI_DEVICE_ELANSPI (dev); FpiDeviceElanSpi *self = FPI_DEVICE_ELANSPI (dev);
ptrdiff_t outptr = 0, inptr = 0;
guint16 value = 0;
if (error) if (error)
{ {
@@ -699,24 +706,39 @@ elanspi_capture_hv_image_handler (FpiSpiTransfer *transfer, FpDevice *dev, gpoin
return; return;
} }
int i, outptr; if (fpi_device_get_driver_data (dev) & ELANSPI_QUIRK_X571)
guint16 value = 0;
for (i = 0, outptr = 0; i < transfer->length_rd && outptr < (self->sensor_height * self->sensor_width * 2); i += 1)
{ {
if (transfer->buffer_rd[i] != 0xff) /* decode image in x571 mode (just copy and fix endian) */
for (int y = 0; y < self->sensor_height; y += 1)
{ {
if (outptr % 2) inptr += 2; /* 2 dummy bytes per line at start */
for (int x = 0; x < self->sensor_width; x += 1)
{ {
value <<= 8; self->last_image[outptr / 2] = transfer->buffer_rd[inptr] + transfer->buffer_rd[inptr + 1] * 0x100;
value |= transfer->buffer_rd[i]; inptr += 2;
self->last_image[outptr / 2] = value; outptr += 2;
} }
else }
}
else
{
/* decode image (normal case; with weird 0xff checks) */
for (inptr = 0, outptr = 0; inptr < transfer->length_rd && outptr < (self->sensor_height * self->sensor_width * 2); inptr += 1)
{
if (transfer->buffer_rd[inptr] != 0xff)
{ {
value = transfer->buffer_rd[i]; if (outptr % 2)
{
value <<= 8;
value |= transfer->buffer_rd[inptr];
self->last_image[outptr / 2] = value;
}
else
{
value = transfer->buffer_rd[inptr];
}
outptr += 1;
} }
outptr += 1;
} }
} }
@@ -774,12 +796,17 @@ elanspi_capture_hv_handler (FpiSsm *ssm, FpDevice *dev)
return; return;
} }
/* otherwise, read the image /* otherwise, read the image
* the hv sensors seem to use 128 bytes of padding(?) this is only tested on the 0xe sensors */ * the hv sensors seem to use variable-length padding(?) this is only tested on the 0xe sensors
*
* in the x571 mode, the padding appears to be disabled and it just has 2 bytes of junk */
xfer = fpi_spi_transfer_new (dev, self->spi_fd); xfer = fpi_spi_transfer_new (dev, self->spi_fd);
xfer->ssm = ssm; xfer->ssm = ssm;
fpi_spi_transfer_write (xfer, 2); fpi_spi_transfer_write (xfer, 2);
xfer->buffer_wr[0] = 0x10; /* receieve line */ xfer->buffer_wr[0] = 0x10; /* receieve line/image */
fpi_spi_transfer_read (xfer, self->sensor_height * (self->sensor_width * 2 + 48)); if (fpi_device_get_driver_data (dev) & ELANSPI_QUIRK_X571)
fpi_spi_transfer_read (xfer, self->sensor_height * (self->sensor_width * 2 + 2) - 2);
else
fpi_spi_transfer_read (xfer, self->sensor_height * (self->sensor_width * 2 + 48));
fpi_spi_transfer_submit (xfer, fpi_device_get_cancellable (dev), elanspi_capture_hv_image_handler, NULL); fpi_spi_transfer_submit (xfer, fpi_device_get_cancellable (dev), elanspi_capture_hv_image_handler, NULL);
return; return;
} }
@@ -873,7 +900,7 @@ elanspi_calibrate_hv_handler (FpiSsm *ssm, FpDevice *dev)
case ELANSPI_CALIBHV_PROCESS: case ELANSPI_CALIBHV_PROCESS:
/* compute mean */ /* compute mean */
mean_diff = abs (elanspi_mean_image (self, self->last_image) - ELANSPI_HV_CALIBRATION_TARGET_MEAN); mean_diff = abs (elanspi_mean_image (self, self->last_image) - self->hv_data.target_mean);
if (mean_diff < 100) if (mean_diff < 100)
{ {
fp_dbg ("<calibhv> calibration ok (mdiff < 100 w/ gdac=%04x)", self->hv_data.gdac_value); fp_dbg ("<calibhv> calibration ok (mdiff < 100 w/ gdac=%04x)", self->hv_data.gdac_value);
@@ -896,7 +923,7 @@ elanspi_calibrate_hv_handler (FpiSsm *ssm, FpDevice *dev)
return; return;
} }
/* update gdac */ /* update gdac */
if (elanspi_mean_image (self, self->last_image) < ELANSPI_HV_CALIBRATION_TARGET_MEAN) if (elanspi_mean_image (self, self->last_image) < self->hv_data.target_mean)
self->hv_data.gdac_value -= self->hv_data.gdac_step; self->hv_data.gdac_value -= self->hv_data.gdac_step;
else else
self->hv_data.gdac_value += self->hv_data.gdac_step; self->hv_data.gdac_value += self->hv_data.gdac_step;
+157 -19
View File
@@ -71,6 +71,7 @@ struct elanspi_regtable
struct struct
{ {
unsigned char sid; unsigned char sid;
unsigned quirk;
const struct elanspi_reg_entry *table; const struct elanspi_reg_entry *table;
} entries[]; } entries[];
}; };
@@ -172,11 +173,11 @@ static const struct elanspi_reg_entry elanspi_calibration_table_id0[] = {
static const struct elanspi_regtable elanspi_calibration_table_old = { static const struct elanspi_regtable elanspi_calibration_table_old = {
.other = elanspi_calibration_table_default, .other = elanspi_calibration_table_default,
.entries = { .entries = {
{ .sid = 0x0, .table = elanspi_calibration_table_id0 }, { .sid = 0x0, .quirk = 0, .table = elanspi_calibration_table_id0 },
{ .sid = 0x5, .table = elanspi_calibration_table_id57 }, { .sid = 0x5, .quirk = 0, .table = elanspi_calibration_table_id57 },
{ .sid = 0x6, .table = elanspi_calibration_table_id6 }, { .sid = 0x6, .quirk = 0, .table = elanspi_calibration_table_id6 },
{ .sid = 0x7, .table = elanspi_calibration_table_id57 }, { .sid = 0x7, .quirk = 0, .table = elanspi_calibration_table_id57 },
{ .sid = 0x0, .table = NULL } { .sid = 0x0, .quirk = 0, .table = NULL }
} }
}; };
@@ -312,20 +313,133 @@ static const struct elanspi_reg_entry elanspi_calibration_table_page1_id14[] = {
{0xff, 0xff} {0xff, 0xff}
}; };
static const struct elanspi_regtable elanspi_calibration_table_new_page0 = { static const struct elanspi_reg_entry elanspi_calibration_table_page0_id14_x571[] = {
.other = NULL, {0x00, 0x5a},
.entries = { {0x01, 0x00},
{ .sid = 0xe, .table = elanspi_calibration_table_page0_id14 }, {0x02, 0x4f},
{ .sid = 0x0, .table = NULL } {0x03, 0x00},
} {0x09, 0x04},
{0x04, 0x4f},
{0x05, 0xa0},
{0x06, 0x57},
{0x07, 0x02},
{0x08, 0x00},
{0x0a, 0x63},
{0x0b, 0x01},
{0x0c, 0x08},
{0x0d, 0x00},
{0x0e, 0x00},
{0x0f, 0x13},
{0x10, 0x38},
{0x11, 0x01},
{0x12, 0x04},
{0x13, 0x00},
{0x14, 0x00},
{0x15, 0x04},
{0x16, 0x02},
{0x17, 0x00},
{0x18, 0x01},
{0x19, 0xf4},
{0x1a, 0x00},
{0x1b, 0x00},
{0x1c, 0x00},
{0x1d, 0x00},
{0x1e, 0x00},
{0x1f, 0x00},
{0x20, 0x00},
{0x21, 0x00},
{0x22, 0x06},
{0x23, 0x00},
{0x24, 0x00},
{0x25, 0x00},
{0x26, 0x00},
{0x27, 0xff},
{0x28, 0x00},
{0x29, 0x04},
{0x2b, 0xe2},
{0x2e, 0xd0},
{0x2f, 0x40},
{0x30, 0x01},
{0x31, 0x38},
{0x32, 0x00},
{0x33, 0x00},
{0x34, 0x00},
{0x35, 0x1f},
{0x36, 0xff},
{0x37, 0x00},
{0x38, 0x00},
{0x39, 0x00},
{0x3a, 0x00},
{0x2a, 0x5f},
{0x2c, 0x10},
{0xff, 0xff}
}; };
static const struct elanspi_regtable elanspi_calibration_table_new_page1 = { static const struct elanspi_reg_entry elanspi_calibration_table_page1_id14_x571[] = {
.other = NULL, {0x00, 0xfb},
.entries = { {0x01, 0xff},
{ .sid = 0xe, .table = elanspi_calibration_table_page1_id14 }, {0x02, 0x7f},
{ .sid = 0x0, .table = NULL } {0x03, 0xd4},
} {0x04, 0x7d},
{0x05, 0x19},
{0x06, 0x80},
{0x07, 0x40},
{0x08, 0x11},
{0x09, 0x00},
{0x0a, 0x00},
{0x0b, 0x00},
{0x0c, 0x00},
{0x0d, 0x00},
{0x0e, 0x32},
{0x0f, 0x00},
{0x10, 0x00},
{0x11, 0x32},
{0x12, 0x02},
{0x13, 0x08},
{0x14, 0x5c},
{0x15, 0x01},
{0x16, 0x15},
{0x17, 0x01},
{0x18, 0x14},
{0x19, 0x01},
{0x1a, 0x14},
{0x1b, 0x01},
{0x1c, 0x16},
{0x1d, 0x01},
{0x1e, 0x0b},
{0x1f, 0x01},
{0x20, 0x0b},
{0x21, 0x02},
{0x22, 0x08},
{0x23, 0x29},
{0x24, 0x00},
{0x25, 0x0c},
{0x26, 0x1b},
{0x27, 0x15},
{0x28, 0x1b},
{0x29, 0x15},
{0x2a, 0x00},
{0x2b, 0x00},
{0x2c, 0x01},
{0x2d, 0x16},
{0x2e, 0x01},
{0x2f, 0x16},
{0x30, 0x04},
{0x31, 0x44},
{0x32, 0x04},
{0x33, 0x44},
{0x34, 0x14},
{0x35, 0x00},
{0x36, 0x00},
{0x37, 0x00},
{0x38, 0x00},
{0x39, 0x03},
{0x3a, 0xfe},
{0x3b, 0x00},
{0x3c, 0x00},
{0x3d, 0x02},
{0x3e, 0x00},
{0x3f, 0x00}
}; };
#define ELANSPI_NO_ROTATE 0 #define ELANSPI_NO_ROTATE 0
@@ -335,10 +449,33 @@ static const struct elanspi_regtable elanspi_calibration_table_new_page1 = {
#define ELANSPI_HV_FLIPPED 1 #define ELANSPI_HV_FLIPPED 1
#define ELANSPI_ROTATE_MASK 3
#define ELANSPI_QUIRK_X571 (1 << 2)
#define ELANSPI_QUIRK_MASK (ELANSPI_QUIRK_X571)
#define ELANSPI_UDEV_TYPES FPI_DEVICE_UDEV_SUBTYPE_SPIDEV | FPI_DEVICE_UDEV_SUBTYPE_HIDRAW #define ELANSPI_UDEV_TYPES FPI_DEVICE_UDEV_SUBTYPE_SPIDEV | FPI_DEVICE_UDEV_SUBTYPE_HIDRAW
#define ELANSPI_TP_VID 0x04f3 #define ELANSPI_TP_VID 0x04f3
// using checkargs ACPI:HIDPID static const struct elanspi_regtable elanspi_calibration_table_new_page0 = {
.other = NULL,
.entries = {
{ .sid = 0xe, .quirk = 0, .table = elanspi_calibration_table_page0_id14 },
{ .sid = 0xe, .quirk = ELANSPI_QUIRK_X571, .table = elanspi_calibration_table_page0_id14_x571 },
{ .sid = 0x0, .table = NULL }
}
};
static const struct elanspi_regtable elanspi_calibration_table_new_page1 = {
.other = NULL,
.entries = {
{ .sid = 0xe, .quirk = 0, .table = elanspi_calibration_table_page1_id14 },
{ .sid = 0xe, .quirk = ELANSPI_QUIRK_X571, .table = elanspi_calibration_table_page1_id14_x571 },
{ .sid = 0x0, .table = NULL }
}
};
static const FpIdEntry elanspi_id_table[] = { static const FpIdEntry elanspi_id_table[] = {
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3057}, .driver_data = ELANSPI_180_ROTATE}, {.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3057}, .driver_data = ELANSPI_180_ROTATE},
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3087}, .driver_data = ELANSPI_180_ROTATE}, {.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3087}, .driver_data = ELANSPI_180_ROTATE},
@@ -348,7 +485,7 @@ static const FpIdEntry elanspi_id_table[] = {
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE}, {.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE},
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN70A1", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE}, {.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN70A1", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE},
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x309f}, .driver_data = ELANSPI_180_ROTATE}, {.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x309f}, .driver_data = ELANSPI_180_ROTATE},
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x241f}, .driver_data = ELANSPI_NO_ROTATE}, {.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3104}, .driver_data = ELANSPI_QUIRK_X571 | ELANSPI_90RIGHT_ROTATE},
{.udev_types = 0} {.udev_types = 0}
}; };
@@ -358,6 +495,7 @@ static const FpIdEntry elanspi_id_table[] = {
#define ELANSPI_MAX_OLD_STAGE2_CALBIRATION_MEAN 8000 #define ELANSPI_MAX_OLD_STAGE2_CALBIRATION_MEAN 8000
#define ELANSPI_HV_CALIBRATION_TARGET_MEAN 3000 #define ELANSPI_HV_CALIBRATION_TARGET_MEAN 3000
#define ELANSPI_HV_X571_CALIBRATION_TARGET_MEAN 7000
#define ELANSPI_MIN_EMPTY_INVALID_PERCENT 6 #define ELANSPI_MIN_EMPTY_INVALID_PERCENT 6
#define ELANSPI_MAX_REAL_INVALID_PERCENT 3 #define ELANSPI_MAX_REAL_INVALID_PERCENT 3
-1
View File
@@ -225,7 +225,6 @@ cmd_interrupt_cb (FpiUsbTransfer *transfer,
} }
else else
{ {
fpi_device_critical_leave (device);
fpi_usb_transfer_submit (fpi_usb_transfer_ref (transfer), fpi_usb_transfer_submit (fpi_usb_transfer_ref (transfer),
0, 0,
NULL, NULL,
-3
View File
@@ -130,9 +130,6 @@ typedef struct
void match_data_free (FpMatchData *match_data); void match_data_free (FpMatchData *match_data);
void fpi_device_suspend (FpDevice *device);
void fpi_device_resume (FpDevice *device);
void fpi_device_configure_wakeup (FpDevice *device, void fpi_device_configure_wakeup (FpDevice *device,
gboolean enabled); gboolean enabled);
void fpi_device_update_temp (FpDevice *device, void fpi_device_update_temp (FpDevice *device,
+87 -2
View File
@@ -949,6 +949,16 @@ fp_device_close_finish (FpDevice *device,
return g_task_propagate_boolean (G_TASK (result), error); return g_task_propagate_boolean (G_TASK (result), error);
} }
static void
complete_suspend_resume_task (FpDevice *device)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_assert (priv->suspend_resume_task);
g_task_return_boolean (g_steal_pointer (&priv->suspend_resume_task), TRUE);
}
/** /**
* fp_device_suspend: * fp_device_suspend:
* @device: a #FpDevice * @device: a #FpDevice
@@ -999,7 +1009,48 @@ fp_device_suspend (FpDevice *device,
priv->suspend_resume_task = g_steal_pointer (&task); priv->suspend_resume_task = g_steal_pointer (&task);
fpi_device_suspend (device); /* If the device is currently idle, just complete immediately.
* For long running tasks, call the driver handler right away, for short
* tasks, wait for completion and then return the task.
*/
switch (priv->current_action)
{
case FPI_DEVICE_ACTION_NONE:
fpi_device_suspend_complete (device, NULL);
break;
case FPI_DEVICE_ACTION_ENROLL:
case FPI_DEVICE_ACTION_VERIFY:
case FPI_DEVICE_ACTION_IDENTIFY:
case FPI_DEVICE_ACTION_CAPTURE:
if (FP_DEVICE_GET_CLASS (device)->suspend)
{
if (priv->critical_section)
priv->suspend_queued = TRUE;
else
FP_DEVICE_GET_CLASS (device)->suspend (device);
}
else
{
fpi_device_suspend_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
}
break;
default:
case FPI_DEVICE_ACTION_PROBE:
case FPI_DEVICE_ACTION_OPEN:
case FPI_DEVICE_ACTION_CLOSE:
case FPI_DEVICE_ACTION_DELETE:
case FPI_DEVICE_ACTION_LIST:
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
g_signal_connect_object (priv->current_task,
"notify::completed",
G_CALLBACK (complete_suspend_resume_task),
device,
G_CONNECT_SWAPPED);
break;
}
} }
/** /**
@@ -1064,7 +1115,41 @@ fp_device_resume (FpDevice *device,
priv->suspend_resume_task = g_steal_pointer (&task); priv->suspend_resume_task = g_steal_pointer (&task);
fpi_device_resume (device); switch (priv->current_action)
{
case FPI_DEVICE_ACTION_NONE:
fpi_device_resume_complete (device, NULL);
break;
case FPI_DEVICE_ACTION_ENROLL:
case FPI_DEVICE_ACTION_VERIFY:
case FPI_DEVICE_ACTION_IDENTIFY:
case FPI_DEVICE_ACTION_CAPTURE:
if (FP_DEVICE_GET_CLASS (device)->resume)
{
if (priv->critical_section)
priv->resume_queued = TRUE;
else
FP_DEVICE_GET_CLASS (device)->resume (device);
}
else
{
fpi_device_resume_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
}
break;
default:
case FPI_DEVICE_ACTION_PROBE:
case FPI_DEVICE_ACTION_OPEN:
case FPI_DEVICE_ACTION_CLOSE:
case FPI_DEVICE_ACTION_DELETE:
case FPI_DEVICE_ACTION_LIST:
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
/* cannot happen as we make sure these tasks complete before suspend */
g_assert_not_reached ();
complete_suspend_resume_task (device);
break;
}
} }
/** /**
+32 -152
View File
@@ -866,16 +866,16 @@ fpi_device_critical_section_flush_idle_cb (FpDevice *device)
if (priv->suspend_queued) if (priv->suspend_queued)
{ {
cls->suspend (device);
priv->suspend_queued = FALSE; priv->suspend_queued = FALSE;
fpi_device_suspend (device);
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }
if (priv->resume_queued) if (priv->resume_queued)
{ {
cls->resume (device);
priv->resume_queued = FALSE; priv->resume_queued = FALSE;
fpi_device_resume (device);
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }
@@ -912,7 +912,6 @@ fpi_device_critical_leave (FpDevice *device)
return; return;
priv->critical_section_flush_source = g_idle_source_new (); priv->critical_section_flush_source = g_idle_source_new ();
g_source_set_priority (priv->critical_section_flush_source, G_PRIORITY_HIGH);
g_source_set_callback (priv->critical_section_flush_source, g_source_set_callback (priv->critical_section_flush_source,
(GSourceFunc) fpi_device_critical_section_flush_idle_cb, (GSourceFunc) fpi_device_critical_section_flush_idle_cb,
device, device,
@@ -1551,148 +1550,6 @@ fpi_device_list_complete (FpDevice *device,
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error); fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
} }
static int
update_attr (const char *attr, const char *value)
{
int fd, err;
gssize r;
char buf[50] = { 0 };
fd = open (attr, O_RDONLY);
err = -errno;
if (fd < 0)
return -err;
r = read (fd, buf, sizeof (buf) - 1);
err = errno;
close (fd);
if (r < 0)
return -err;
g_strchomp (buf);
if (g_strcmp0 (buf, value) == 0)
return 0;
/* O_TRUNC makes things work in the umockdev environment */
fd = open (attr, O_WRONLY | O_TRUNC);
err = errno;
if (fd < 0)
return -err;
r = write (fd, value, strlen (value));
err = -errno;
close (fd);
if (r < 0)
{
/* Write failures are weird, and are worth a warning */
g_warning ("Could not write %s to %s", value, attr);
return -err;
}
return 0;
}
static void
complete_suspend_resume_task (FpDevice *device)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_assert (priv->suspend_resume_task);
g_task_return_boolean (g_steal_pointer (&priv->suspend_resume_task), TRUE);
}
void
fpi_device_suspend (FpDevice *device)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
/* If the device is currently idle, just complete immediately.
* For long running tasks, call the driver handler right away, for short
* tasks, wait for completion and then return the task.
*/
switch (priv->current_action)
{
case FPI_DEVICE_ACTION_NONE:
fpi_device_suspend_complete (device, NULL);
break;
case FPI_DEVICE_ACTION_ENROLL:
case FPI_DEVICE_ACTION_VERIFY:
case FPI_DEVICE_ACTION_IDENTIFY:
case FPI_DEVICE_ACTION_CAPTURE:
if (FP_DEVICE_GET_CLASS (device)->suspend)
{
if (priv->critical_section)
priv->suspend_queued = TRUE;
else
FP_DEVICE_GET_CLASS (device)->suspend (device);
}
else
{
fpi_device_suspend_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
}
break;
default:
case FPI_DEVICE_ACTION_PROBE:
case FPI_DEVICE_ACTION_OPEN:
case FPI_DEVICE_ACTION_CLOSE:
case FPI_DEVICE_ACTION_DELETE:
case FPI_DEVICE_ACTION_LIST:
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
g_signal_connect_object (priv->current_task,
"notify::completed",
G_CALLBACK (complete_suspend_resume_task),
device,
G_CONNECT_SWAPPED);
break;
}
}
void
fpi_device_resume (FpDevice *device)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
switch (priv->current_action)
{
case FPI_DEVICE_ACTION_NONE:
fpi_device_resume_complete (device, NULL);
break;
case FPI_DEVICE_ACTION_ENROLL:
case FPI_DEVICE_ACTION_VERIFY:
case FPI_DEVICE_ACTION_IDENTIFY:
case FPI_DEVICE_ACTION_CAPTURE:
if (FP_DEVICE_GET_CLASS (device)->resume)
{
if (priv->critical_section)
priv->resume_queued = TRUE;
else
FP_DEVICE_GET_CLASS (device)->resume (device);
}
else
{
fpi_device_resume_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
}
break;
default:
case FPI_DEVICE_ACTION_PROBE:
case FPI_DEVICE_ACTION_OPEN:
case FPI_DEVICE_ACTION_CLOSE:
case FPI_DEVICE_ACTION_DELETE:
case FPI_DEVICE_ACTION_LIST:
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
/* cannot happen as we make sure these tasks complete before suspend */
g_assert_not_reached ();
complete_suspend_resume_task (device);
break;
}
}
void void
fpi_device_configure_wakeup (FpDevice *device, gboolean enabled) fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
{ {
@@ -1708,7 +1565,8 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
guint8 bus, port; guint8 bus, port;
g_autofree gchar *sysfs_wakeup = NULL; g_autofree gchar *sysfs_wakeup = NULL;
g_autofree gchar *sysfs_persist = NULL; g_autofree gchar *sysfs_persist = NULL;
int res; gssize r;
int fd;
ports = g_string_new (NULL); ports = g_string_new (NULL);
bus = g_usb_device_get_bus (priv->usb_device); bus = g_usb_device_get_bus (priv->usb_device);
@@ -1724,9 +1582,20 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
g_string_set_size (ports, ports->len - 1); g_string_set_size (ports, ports->len - 1);
sysfs_wakeup = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/wakeup", bus, ports->str); sysfs_wakeup = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/wakeup", bus, ports->str);
res = update_attr (sysfs_wakeup, wakeup_command); fd = open (sysfs_wakeup, O_WRONLY);
if (res < 0)
g_debug ("Failed to set %s to %s", sysfs_wakeup, wakeup_command); if (fd < 0)
{
/* Wakeup not existing appears to be relatively normal. */
g_debug ("Failed to open %s", sysfs_wakeup);
}
else
{
r = write (fd, wakeup_command, strlen (wakeup_command));
if (r < 0)
g_warning ("Could not configure wakeup to %s by writing %s", wakeup_command, sysfs_wakeup);
close (fd);
}
/* Persist means that the kernel tries to keep the USB device open /* Persist means that the kernel tries to keep the USB device open
* in case it is "replugged" due to suspend. * in case it is "replugged" due to suspend.
@@ -1734,9 +1603,20 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
* state. Instead, seeing an unplug and a new device makes more sense. * state. Instead, seeing an unplug and a new device makes more sense.
*/ */
sysfs_persist = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/persist", bus, ports->str); sysfs_persist = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/persist", bus, ports->str);
res = update_attr (sysfs_persist, "0"); fd = open (sysfs_persist, O_WRONLY);
if (res < 0)
g_warning ("Failed to disable USB persist by writing to %s", sysfs_persist); if (fd < 0)
{
g_warning ("Failed to open %s", sysfs_persist);
return;
}
else
{
r = write (fd, "0", 1);
if (r < 0)
g_message ("Could not disable USB persist by writing to %s", sysfs_persist);
close (fd);
}
break; break;
} }
+1 -1
View File
@@ -277,7 +277,7 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
{ {
print = fp_print_new (device); print = fp_print_new (device);
fpi_print_set_type (print, FPI_PRINT_NBIS); fpi_print_set_type (print, FPI_PRINT_NBIS);
if (!fpi_print_add_from_image (print, image, priv->bz3_threshold, &error)) if (!fpi_print_add_from_image (print, image, &error))
{ {
g_clear_object (&print); g_clear_object (&print);
+4 -20
View File
@@ -154,14 +154,11 @@ minutiae_to_xyt (struct fp_minutiae *minutiae,
gboolean gboolean
fpi_print_add_from_image (FpPrint *print, fpi_print_add_from_image (FpPrint *print,
FpImage *image, FpImage *image,
gint bz3_threshold,
GError **error) GError **error)
{ {
g_autofree struct xyt_struct *xyt = NULL;
GPtrArray *minutiae; GPtrArray *minutiae;
struct fp_minutiae _minutiae; struct fp_minutiae _minutiae;
gint probe_len; struct xyt_struct *xyt;
gint score;
if (print->type != FPI_PRINT_NBIS || !image) if (print->type != FPI_PRINT_NBIS || !image)
{ {
@@ -176,8 +173,8 @@ fpi_print_add_from_image (FpPrint *print,
if (!minutiae || minutiae->len == 0) if (!minutiae || minutiae->len == 0)
{ {
g_set_error (error, g_set_error (error,
FP_DEVICE_RETRY, G_IO_ERROR,
FP_DEVICE_RETRY_GENERAL, G_IO_ERROR_INVALID_DATA,
"No minutiae found in image or not yet detected!"); "No minutiae found in image or not yet detected!");
return FALSE; return FALSE;
} }
@@ -188,20 +185,7 @@ fpi_print_add_from_image (FpPrint *print,
xyt = g_new0 (struct xyt_struct, 1); xyt = g_new0 (struct xyt_struct, 1);
minutiae_to_xyt (&_minutiae, image->width, image->height, xyt); minutiae_to_xyt (&_minutiae, image->width, image->height, xyt);
g_ptr_array_add (print->prints, xyt);
probe_len = bozorth_probe_init (xyt);
score = bozorth_to_gallery (probe_len, xyt, xyt);
fp_dbg ("self-match score %d/%d", score, bz3_threshold);
if (score <= bz3_threshold)
{
g_set_error (error,
FP_DEVICE_RETRY,
FP_DEVICE_RETRY_GENERAL,
"Not enough minutiae to generate a match!");
return FPI_MATCH_SUCCESS;
}
g_ptr_array_add (print->prints, g_steal_pointer (&xyt));
g_clear_object (&print->image); g_clear_object (&print->image);
print->image = g_object_ref (image); print->image = g_object_ref (image);
-1
View File
@@ -40,7 +40,6 @@ void fpi_print_set_device_stored (FpPrint *print,
gboolean fpi_print_add_from_image (FpPrint *print, gboolean fpi_print_add_from_image (FpPrint *print,
FpImage *image, FpImage *image,
gint bz3_threshold,
GError **error); GError **error);
FpiMatchResult fpi_print_bz3_match (FpPrint * template, FpiMatchResult fpi_print_bz3_match (FpPrint * template,
-5
View File
@@ -105,11 +105,6 @@ process.wait()
# Run capture # Run capture
# https://osqa-ask.wireshark.org/questions/53919/how-can-i-precisely-specify-a-usb-device-to-capture-with-tshark/ # https://osqa-ask.wireshark.org/questions/53919/how-can-i-precisely-specify-a-usb-device-to-capture-with-tshark/
print(f'### Reseting USB port (as descriptors could be missing in the dump otherwise)')
usb_device.open()
usb_device.reset()
usb_device.close()
print(f'### Starting USB capture on usbmon{bus_num}') print(f'### Starting USB capture on usbmon{bus_num}')
capture_pid = os.fork() capture_pid = os.fork()
assert(capture_pid >= 0) assert(capture_pid >= 0)
Binary file not shown.
+2 -39
View File
@@ -1,14 +1,10 @@
#!/usr/bin/python3 #!/usr/bin/python3
import os
import gi import gi
gi.require_version('FPrint', '2.0') gi.require_version('FPrint', '2.0')
from gi.repository import FPrint, GLib from gi.repository import FPrint, GLib
import sys ctx = GLib.main_context_default()
import traceback
sys.excepthook = lambda *args : (traceback.print_exception(*args), sys.exit(1))
c = FPrint.Context() c = FPrint.Context()
c.enumerate() c.enumerate()
@@ -17,24 +13,6 @@ devices = c.get_devices()
d = devices[0] d = devices[0]
del devices del devices
usb_device = d.get_property('fpi-usb-device')
bus_num = usb_device.get_bus()
port = []
while True:
parent = usb_device.get_parent()
if parent is None:
break
port.append(str(usb_device.get_port_number()))
usb_device = parent
port = '.'.join(port)
persist = f'/sys/bus/usb/devices/{bus_num}-{port}/power/persist'
wakeup = f'/sys/bus/usb/devices/{bus_num}-{port}/power/wakeup'
# may not have written anything
assert open(persist).read().strip() == "0"
assert open(wakeup).read().strip() == "disabled"
assert d.get_driver() == "synaptics" assert d.get_driver() == "synaptics"
assert not d.has_feature(FPrint.DeviceFeature.CAPTURE) assert not d.has_feature(FPrint.DeviceFeature.CAPTURE)
assert d.has_feature(FPrint.DeviceFeature.IDENTIFY) assert d.has_feature(FPrint.DeviceFeature.IDENTIFY)
@@ -51,7 +29,7 @@ d.clear_storage_sync()
template = FPrint.Print.new(d) template = FPrint.Print.new(d)
def enroll_progress(*args): def enroll_progress(*args):
#assert d.get_finger_status() == FPrint.FingerStatusFlags.NEEDED assert d.get_finger_status() == FPrint.FingerStatusFlags.NEEDED
print('enroll progress: ' + str(args)) print('enroll progress: ' + str(args))
# List, enroll, list, verify, delete, list # List, enroll, list, verify, delete, list
@@ -63,21 +41,6 @@ print("enroll done")
print("verifying") print("verifying")
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
# Inject a suspend/resume cycle into the verify
def suspend_resume():
d.suspend_sync()
assert open(persist).read().strip() == "0"
assert open(wakeup).read().strip() == "enabled"
assert open(persist, 'w').write('0\n')
d.resume_sync()
# This tests that libfprint doesn't write if the value is correct
# (i.e. the trailing \ would be lost inside umockdev if written)
assert open(persist).read() == "0\n"
assert open(wakeup).read().strip() == "disabled"
GLib.idle_add(suspend_resume, priority=GLib.PRIORITY_HIGH)
verify_res, verify_print = d.verify_sync(p) verify_res, verify_print = d.verify_sync(p)
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
print("verify done") print("verify done")
+147 -147
View File
@@ -1,14 +1,14 @@
P: /devices/pci0000:00/0000:00:14.0/usb1/1-9 P: /devices/pci0000:00/0000:00:14.0/usb1/1-9
N: bus/usb/001/004=12010002FF10FF08CB06BD0000000000010109022700010100A0320904000003FF000000070501024000000705810240000007058303080004 N: bus/usb/001/005
E: DEVNAME=/dev/bus/usb/001/004 E: DEVNAME=/dev/bus/usb/001/005
E: DEVTYPE=usb_device E: DEVTYPE=usb_device
E: DRIVER=usb E: DRIVER=usb
E: PRODUCT=6cb/bd/0 E: PRODUCT=6cb/bd/0
E: TYPE=255/16/255 E: TYPE=255/16/255
E: BUSNUM=001 E: BUSNUM=001
E: DEVNUM=004 E: DEVNUM=005
E: MAJOR=189 E: MAJOR=189
E: MINOR=3 E: MINOR=4
E: SUBSYSTEM=usb E: SUBSYSTEM=usb
E: ID_VENDOR=06cb E: ID_VENDOR=06cb
E: ID_VENDOR_ENC=06cb E: ID_VENDOR_ENC=06cb
@@ -24,82 +24,82 @@ E: ID_USB_INTERFACES=:ff0000:
E: ID_VENDOR_FROM_DATABASE=Synaptics, Inc. E: ID_VENDOR_FROM_DATABASE=Synaptics, Inc.
E: ID_AUTOSUSPEND=1 E: ID_AUTOSUSPEND=1
E: ID_MODEL_FROM_DATABASE=Prometheus MIS Touch Fingerprint Reader E: ID_MODEL_FROM_DATABASE=Prometheus MIS Touch Fingerprint Reader
E: ID_PERSIST=0
E: ID_PATH=pci-0000:00:14.0-usb-0:9 E: ID_PATH=pci-0000:00:14.0-usb-0:9
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9 E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9
A: authorized=1 E: LIBFPRINT_DRIVER=Synaptics Sensors
A: avoid_reset_quirk=0 A: authorized=1\n
A: bConfigurationValue=1 A: avoid_reset_quirk=0\n
A: bDeviceClass=ff A: bConfigurationValue=1\n
A: bDeviceProtocol=ff A: bDeviceClass=ff\n
A: bDeviceSubClass=10 A: bDeviceProtocol=ff\n
A: bMaxPacketSize0=8 A: bDeviceSubClass=10\n
A: bMaxPower=100mA A: bMaxPacketSize0=8\n
A: bNumConfigurations=1 A: bMaxPower=100mA\n
A: bNumInterfaces= 1 A: bNumConfigurations=1\n
A: bcdDevice=0000 A: bNumInterfaces= 1\n
A: bmAttributes=a0 A: bcdDevice=0000\n
A: busnum=1 A: bmAttributes=a0\n
A: busnum=1\n
A: configuration= A: configuration=
H: descriptors=12010002FF10FF08CB06BD0000000000010109022700010100A0320904000003FF000000070501024000000705810240000007058303080004 H: descriptors=12010002FF10FF08CB06BD0000000000010109022700010100A0320904000003FF000000070501024000000705810240000007058303080004
A: dev=189:3 A: dev=189:4\n
A: devnum=4 A: devnum=5\n
A: devpath=9 A: devpath=9\n
L: driver=../../../../../bus/usb/drivers/usb L: driver=../../../../../bus/usb/drivers/usb
L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d/device:28 L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d/device:28
A: idProduct=00bd A: idProduct=00bd\n
A: idVendor=06cb A: idVendor=06cb\n
A: ltm_capable=no A: ltm_capable=no\n
A: maxchild=0 A: maxchild=0\n
L: port=../1-0:1.0/usb1-port9 L: port=../1-0:1.0/usb1-port9
A: power/active_duration=9424964 A: power/active_duration=82065\n
A: power/autosuspend=2 A: power/autosuspend=2\n
A: power/autosuspend_delay_ms=2000 A: power/autosuspend_delay_ms=2000\n
A: power/connected_duration=866169213 A: power/connected_duration=4271349\n
A: power/control=auto A: power/control=auto\n
A: power/level=auto A: power/level=auto\n
A: power/persist=0 A: power/persist=1\n
A: power/runtime_active_time=9431408 A: power/runtime_active_time=82975\n
A: power/runtime_status=active A: power/runtime_status=suspended\n
A: power/runtime_suspended_time=856661633 A: power/runtime_suspended_time=4186597\n
A: power/wakeup=disabled A: power/wakeup=disabled\n
A: power/wakeup_abort_count= A: power/wakeup_abort_count=\n
A: power/wakeup_active= A: power/wakeup_active=\n
A: power/wakeup_active_count= A: power/wakeup_active_count=\n
A: power/wakeup_count= A: power/wakeup_count=\n
A: power/wakeup_expire_count= A: power/wakeup_expire_count=\n
A: power/wakeup_last_time_ms= A: power/wakeup_last_time_ms=\n
A: power/wakeup_max_time_ms= A: power/wakeup_max_time_ms=\n
A: power/wakeup_total_time_ms= A: power/wakeup_total_time_ms=\n
A: quirks=0x0 A: quirks=0x0\n
A: removable=fixed A: removable=fixed\n
A: rx_lanes=1 A: rx_lanes=1\n
A: serial=c087f7d72126 A: serial=c087f7d72126\n
A: speed=12 A: speed=12\n
A: tx_lanes=1 A: tx_lanes=1\n
A: urbnum=8945 A: urbnum=618\n
A: version= 2.00 A: version= 2.00\n
P: /devices/pci0000:00/0000:00:14.0/usb1 P: /devices/pci0000:00/0000:00:14.0/usb1
N: bus/usb/001/001=12010002090001406B1D020016050302010109021900010100E0000904000001090000000705810304000C N: bus/usb/001/001=12010002090001406B1D020012050302010109021900010100E0000904000001090000000705810304000C
E: DEVNAME=/dev/bus/usb/001/001 E: DEVNAME=/dev/bus/usb/001/001
E: DEVTYPE=usb_device E: DEVTYPE=usb_device
E: DRIVER=usb E: DRIVER=usb
E: PRODUCT=1d6b/2/516 E: PRODUCT=1d6b/2/512
E: TYPE=9/0/1 E: TYPE=9/0/1
E: BUSNUM=001 E: BUSNUM=001
E: DEVNUM=001 E: DEVNUM=001
E: MAJOR=189 E: MAJOR=189
E: MINOR=0 E: MINOR=0
E: SUBSYSTEM=usb E: SUBSYSTEM=usb
E: ID_VENDOR=Linux_5.16.8-200.fc35.x86_64_xhci-hcd E: ID_VENDOR=Linux_5.12.9-300.fc34.x86_64_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.16.8-200.fc35.x86_64\x20xhci-hcd E: ID_VENDOR_ENC=Linux\x205.12.9-300.fc34.x86_64\x20xhci-hcd
E: ID_VENDOR_ID=1d6b E: ID_VENDOR_ID=1d6b
E: ID_MODEL=xHCI_Host_Controller E: ID_MODEL=xHCI_Host_Controller
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_MODEL_ID=0002 E: ID_MODEL_ID=0002
E: ID_REVISION=0516 E: ID_REVISION=0512
E: ID_SERIAL=Linux_5.16.8-200.fc35.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 E: ID_SERIAL=Linux_5.12.9-300.fc34.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
E: ID_SERIAL_SHORT=0000:00:14.0 E: ID_SERIAL_SHORT=0000:00:14.0
E: ID_BUS=usb E: ID_BUS=usb
E: ID_USB_INTERFACES=:090000: E: ID_USB_INTERFACES=:090000:
@@ -111,60 +111,60 @@ E: ID_PATH_TAG=pci-0000_00_14_0
E: ID_FOR_SEAT=usb-pci-0000_00_14_0 E: ID_FOR_SEAT=usb-pci-0000_00_14_0
E: TAGS=:seat: E: TAGS=:seat:
E: CURRENT_TAGS=:seat: E: CURRENT_TAGS=:seat:
A: authorized=1 A: authorized=1\n
A: authorized_default=1 A: authorized_default=1\n
A: avoid_reset_quirk=0 A: avoid_reset_quirk=0\n
A: bConfigurationValue=1 A: bConfigurationValue=1\n
A: bDeviceClass=09 A: bDeviceClass=09\n
A: bDeviceProtocol=01 A: bDeviceProtocol=01\n
A: bDeviceSubClass=00 A: bDeviceSubClass=00\n
A: bMaxPacketSize0=64 A: bMaxPacketSize0=64\n
A: bMaxPower=0mA A: bMaxPower=0mA\n
A: bNumConfigurations=1 A: bNumConfigurations=1\n
A: bNumInterfaces= 1 A: bNumInterfaces= 1\n
A: bcdDevice=0516 A: bcdDevice=0512\n
A: bmAttributes=e0 A: bmAttributes=e0\n
A: busnum=1 A: busnum=1\n
A: configuration= A: configuration=
H: descriptors=12010002090001406B1D020016050302010109021900010100E0000904000001090000000705810304000C H: descriptors=12010002090001406B1D020012050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0 A: dev=189:0\n
A: devnum=1 A: devnum=1\n
A: devpath=0 A: devpath=0\n
L: driver=../../../../bus/usb/drivers/usb L: driver=../../../../bus/usb/drivers/usb
L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d
A: idProduct=0002 A: idProduct=0002\n
A: idVendor=1d6b A: idVendor=1d6b\n
A: interface_authorized_default=1 A: interface_authorized_default=1\n
A: ltm_capable=no A: ltm_capable=no\n
A: manufacturer=Linux 5.16.8-200.fc35.x86_64 xhci-hcd A: manufacturer=Linux 5.12.9-300.fc34.x86_64 xhci-hcd\n
A: maxchild=12 A: maxchild=12\n
A: power/active_duration=865968060 A: power/active_duration=4270585\n
A: power/autosuspend=0 A: power/autosuspend=0\n
A: power/autosuspend_delay_ms=0 A: power/autosuspend_delay_ms=0\n
A: power/connected_duration=866169920 A: power/connected_duration=4272308\n
A: power/control=auto A: power/control=auto\n
A: power/level=auto A: power/level=auto\n
A: power/runtime_active_time=866093998 A: power/runtime_active_time=4270770\n
A: power/runtime_status=active A: power/runtime_status=active\n
A: power/runtime_suspended_time=0 A: power/runtime_suspended_time=0\n
A: power/wakeup=disabled A: power/wakeup=disabled\n
A: power/wakeup_abort_count= A: power/wakeup_abort_count=\n
A: power/wakeup_active= A: power/wakeup_active=\n
A: power/wakeup_active_count= A: power/wakeup_active_count=\n
A: power/wakeup_count= A: power/wakeup_count=\n
A: power/wakeup_expire_count= A: power/wakeup_expire_count=\n
A: power/wakeup_last_time_ms= A: power/wakeup_last_time_ms=\n
A: power/wakeup_max_time_ms= A: power/wakeup_max_time_ms=\n
A: power/wakeup_total_time_ms= A: power/wakeup_total_time_ms=\n
A: product=xHCI Host Controller A: product=xHCI Host Controller\n
A: quirks=0x0 A: quirks=0x0\n
A: removable=unknown A: removable=unknown\n
A: rx_lanes=1 A: rx_lanes=1\n
A: serial=0000:00:14.0 A: serial=0000:00:14.0\n
A: speed=480 A: speed=480\n
A: tx_lanes=1 A: tx_lanes=1\n
A: urbnum=9372 A: urbnum=463\n
A: version= 2.00 A: version= 2.00\n
P: /devices/pci0000:00/0000:00:14.0 P: /devices/pci0000:00/0000:00:14.0
E: DRIVER=xhci_hcd E: DRIVER=xhci_hcd
@@ -180,44 +180,44 @@ E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
E: ID_VENDOR_FROM_DATABASE=Intel Corporation E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: ID_AUTOSUSPEND=1 E: ID_AUTOSUSPEND=1
E: ID_MODEL_FROM_DATABASE=Cannon Point-LP USB 3.1 xHCI Controller E: ID_MODEL_FROM_DATABASE=Cannon Point-LP USB 3.1 xHCI Controller
A: ari_enabled=0 A: ari_enabled=0\n
A: broken_parity_status=0 A: broken_parity_status=0\n
A: class=0x0c0330 A: class=0x0c0330\n
H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F0000000060069A2400000000316000000000000000000000000000000180C2C108000000000000000000000005908700D802E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000000000000000000008000000040000000000000000000000000000000000000000000000000000000800000004000000000000000000000000000000000000000000000000000000B50F320112000000 H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000
A: consistent_dma_mask_bits=64 A: consistent_dma_mask_bits=64\n
A: d3cold_allowed=1 A: d3cold_allowed=1\n
A: dbc=disabled A: dbc=disabled\n
A: device=0x9ded A: device=0x9ded\n
A: dma_mask_bits=64 A: dma_mask_bits=64\n
L: driver=../../../bus/pci/drivers/xhci_hcd L: driver=../../../bus/pci/drivers/xhci_hcd
A: driver_override=(null) A: driver_override=(null)\n
A: enable=1 A: enable=1\n
L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c
A: irq=126 A: irq=128\n
A: local_cpulist=0-7 A: local_cpulist=0-7\n
A: local_cpus=ff A: local_cpus=ff\n
A: modalias=pci:v00008086d00009DEDsv000017AAsd00002292bc0Csc03i30 A: modalias=pci:v00008086d00009DEDsv000017AAsd00002292bc0Csc03i30\n
A: msi_bus=1 A: msi_bus=1\n
A: msi_irqs/126=msi A: msi_irqs/128=msi\n
A: numa_node=-1 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 21 24 2112 24\nxHCI ring segments 68 80 4096 80\nbuffer-2048 0 38 2048 19\nbuffer-512 0 0 512 0\nbuffer-128 18 32 128 1\nbuffer-32 0 128 32 1 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 9 12 2112 12\nxHCI ring segments 40 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=auto A: power/control=auto\n
A: power/runtime_active_time=866094158 A: power/runtime_active_time=4271635\n
A: power/runtime_status=active A: power/runtime_status=active\n
A: power/runtime_suspended_time=0 A: power/runtime_suspended_time=0\n
A: power/wakeup=enabled A: power/wakeup=enabled\n
A: power/wakeup_abort_count=0 A: power/wakeup_abort_count=0\n
A: power/wakeup_active=0 A: power/wakeup_active=0\n
A: power/wakeup_active_count=2 A: power/wakeup_active_count=0\n
A: power/wakeup_count=0 A: power/wakeup_count=0\n
A: power/wakeup_expire_count=2 A: power/wakeup_expire_count=0\n
A: power/wakeup_last_time_ms=476219021 A: power/wakeup_last_time_ms=0\n
A: power/wakeup_max_time_ms=103 A: power/wakeup_max_time_ms=0\n
A: power/wakeup_total_time_ms=207 A: power/wakeup_total_time_ms=0\n
A: power_state=D0 A: power_state=D0\n
A: resource=0x00000000ea220000 0x00000000ea22ffff 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 A: resource=0x00000000ea220000 0x00000000ea22ffff 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
A: revision=0x11 A: revision=0x11\n
A: subsystem_device=0x2292 A: subsystem_device=0x2292\n
A: subsystem_vendor=0x17aa A: subsystem_vendor=0x17aa\n
A: vendor=0x8086 A: vendor=0x8086\n