Compare commits

..

2 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
14 changed files with 471 additions and 411 deletions

11
NEWS
View File

@@ -1,17 +1,6 @@
This file lists notable changes in each release. For the full history of all This file lists notable changes in each release. For the full history of all
changes, see ChangeLog. changes, see ChangeLog.
2022-05-24: v1.94.4 release
Highlights:
* synaptics: New PIDs 0x0168, 0x015f
* elan: New PID 0x0c4b
* elanspi: New PID 0x241f
* synaptics: Minor fix to interrupt transfer resubmission
* Avoid sysfs writes if value is already expected
* Improvements to the testing setup
* Fixes to the internal critical section API
2021-11-02: v1.94.3 release 2021-11-02: v1.94.3 release
Highlights: Highlights:

View File

@@ -190,7 +190,6 @@ usb:v06CBp0123*
usb:v06CBp0126* usb:v06CBp0126*
usb:v06CBp0129* usb:v06CBp0129*
usb:v06CBp0168* usb:v06CBp0168*
usb:v06CBp015F*
ID_AUTOSUSPEND=1 ID_AUTOSUSPEND=1
ID_PERSIST=0 ID_PERSIST=0
@@ -258,7 +257,6 @@ usb:v138Ap0091*
ID_PERSIST=0 ID_PERSIST=0
# Known unsupported devices # Known unsupported devices
usb:v04E8p730B*
usb:v04F3p036B* usb:v04F3p036B*
usb:v04F3p0C00* usb:v04F3p0C00*
usb:v04F3p0C4C* usb:v04F3p0C4C*
@@ -281,7 +279,6 @@ usb:v06CBp00C9*
usb:v06CBp00D8* usb:v06CBp00D8*
usb:v06CBp00DA* usb:v06CBp00DA*
usb:v06CBp00DC* usb:v06CBp00DC*
usb:v06CBp00E4*
usb:v06CBp00E7* usb:v06CBp00E7*
usb:v06CBp00E9* usb:v06CBp00E9*
usb:v06CBp00FD* usb:v06CBp00FD*
@@ -297,7 +294,6 @@ usb:v0A5Cp5845*
usb:v0BDAp5812* usb:v0BDAp5812*
usb:v10A5p0007* usb:v10A5p0007*
usb:v10A5p9200* usb:v10A5p9200*
usb:v10A5p9800*
usb:v1188p9545* usb:v1188p9545*
usb:v138Ap0007* usb:v138Ap0007*
usb:v138Ap003A* usb:v138Ap003A*
@@ -319,7 +315,6 @@ usb:v1C7Ap0576*
usb:v27C6p5042* usb:v27C6p5042*
usb:v27C6p5110* usb:v27C6p5110*
usb:v27C6p5117* usb:v27C6p5117*
usb:v27C6p5125*
usb:v27C6p5201* usb:v27C6p5201*
usb:v27C6p521D* usb:v27C6p521D*
usb:v27C6p5301* usb:v27C6p5301*
@@ -331,7 +326,6 @@ usb:v27C6p5385*
usb:v27C6p538C* usb:v27C6p538C*
usb:v27C6p538D* usb:v27C6p538D*
usb:v27C6p5395* usb:v27C6p5395*
usb:v27C6p5503*
usb:v27C6p5584* usb:v27C6p5584*
usb:v27C6p55A2* usb:v27C6p55A2*
usb:v27C6p55A4* usb:v27C6p55A4*

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,26 +706,41 @@ 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)
{
inptr += 2; /* 2 dummy bytes per line at start */
for (int x = 0; x < self->sensor_width; x += 1)
{
self->last_image[outptr / 2] = transfer->buffer_rd[inptr] + transfer->buffer_rd[inptr + 1] * 0x100;
inptr += 2;
outptr += 2;
}
}
}
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)
{ {
if (outptr % 2) if (outptr % 2)
{ {
value <<= 8; value <<= 8;
value |= transfer->buffer_rd[i]; value |= transfer->buffer_rd[inptr];
self->last_image[outptr / 2] = value; self->last_image[outptr / 2] = value;
} }
else else
{ {
value = transfer->buffer_rd[i]; value = transfer->buffer_rd[inptr];
} }
outptr += 1; outptr += 1;
} }
} }
}
if (outptr != (self->sensor_height * self->sensor_width * 2)) if (outptr != (self->sensor_height * self->sensor_width * 2))
{ {
@@ -774,11 +796,16 @@ 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 */
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_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;

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

View File

@@ -43,7 +43,6 @@ static const FpIdEntry id_table[] = {
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0126, }, { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0126, },
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0129, }, { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0129, },
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0168, }, { .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0168, },
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x015F, },
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
}; };
@@ -226,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,

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,

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;
}
} }
/** /**

View File

@@ -21,7 +21,6 @@
#define FP_COMPONENT "device" #define FP_COMPONENT "device"
#include <math.h> #include <math.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h>
#include "fpi-log.h" #include "fpi-log.h"
@@ -867,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;
} }
@@ -913,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,
@@ -1552,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)
{ {
@@ -1709,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);
@@ -1725,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.
@@ -1735,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;
} }

View File

@@ -29,7 +29,6 @@ static const FpIdEntry whitelist_id_table[] = {
* You can generate this list from the wiki page using e.g.: * You can generate this list from the wiki page using e.g.:
* gio cat https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md | sed -n 's!|.*\([0-9a-fA-F]\{4\}\):\([0-9a-fA-F]\{4\}\).*|.*! { .vid = 0x\1, .pid = 0x\2 },!p' * gio cat https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md | sed -n 's!|.*\([0-9a-fA-F]\{4\}\):\([0-9a-fA-F]\{4\}\).*|.*! { .vid = 0x\1, .pid = 0x\2 },!p'
*/ */
{ .vid = 0x04e8, .pid = 0x730b },
{ .vid = 0x04f3, .pid = 0x036b }, { .vid = 0x04f3, .pid = 0x036b },
{ .vid = 0x04f3, .pid = 0x0c00 }, { .vid = 0x04f3, .pid = 0x0c00 },
{ .vid = 0x04f3, .pid = 0x0c4c }, { .vid = 0x04f3, .pid = 0x0c4c },
@@ -52,7 +51,6 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x06cb, .pid = 0x00d8 }, { .vid = 0x06cb, .pid = 0x00d8 },
{ .vid = 0x06cb, .pid = 0x00da }, { .vid = 0x06cb, .pid = 0x00da },
{ .vid = 0x06cb, .pid = 0x00dc }, { .vid = 0x06cb, .pid = 0x00dc },
{ .vid = 0x06cb, .pid = 0x00e4 },
{ .vid = 0x06cb, .pid = 0x00e7 }, { .vid = 0x06cb, .pid = 0x00e7 },
{ .vid = 0x06cb, .pid = 0x00e9 }, { .vid = 0x06cb, .pid = 0x00e9 },
{ .vid = 0x06cb, .pid = 0x00fd }, { .vid = 0x06cb, .pid = 0x00fd },
@@ -68,7 +66,6 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x0bda, .pid = 0x5812 }, { .vid = 0x0bda, .pid = 0x5812 },
{ .vid = 0x10a5, .pid = 0x0007 }, { .vid = 0x10a5, .pid = 0x0007 },
{ .vid = 0x10a5, .pid = 0x9200 }, { .vid = 0x10a5, .pid = 0x9200 },
{ .vid = 0x10a5, .pid = 0x9800 },
{ .vid = 0x1188, .pid = 0x9545 }, { .vid = 0x1188, .pid = 0x9545 },
{ .vid = 0x138a, .pid = 0x0007 }, { .vid = 0x138a, .pid = 0x0007 },
{ .vid = 0x138a, .pid = 0x003a }, { .vid = 0x138a, .pid = 0x003a },
@@ -90,7 +87,6 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x27c6, .pid = 0x5042 }, { .vid = 0x27c6, .pid = 0x5042 },
{ .vid = 0x27c6, .pid = 0x5110 }, { .vid = 0x27c6, .pid = 0x5110 },
{ .vid = 0x27c6, .pid = 0x5117 }, { .vid = 0x27c6, .pid = 0x5117 },
{ .vid = 0x27c6, .pid = 0x5125 },
{ .vid = 0x27c6, .pid = 0x5201 }, { .vid = 0x27c6, .pid = 0x5201 },
{ .vid = 0x27c6, .pid = 0x521d }, { .vid = 0x27c6, .pid = 0x521d },
{ .vid = 0x27c6, .pid = 0x5301 }, { .vid = 0x27c6, .pid = 0x5301 },
@@ -102,7 +98,6 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x27c6, .pid = 0x538c }, { .vid = 0x27c6, .pid = 0x538c },
{ .vid = 0x27c6, .pid = 0x538d }, { .vid = 0x27c6, .pid = 0x538d },
{ .vid = 0x27c6, .pid = 0x5395 }, { .vid = 0x27c6, .pid = 0x5395 },
{ .vid = 0x27c6, .pid = 0x5503 },
{ .vid = 0x27c6, .pid = 0x5584 }, { .vid = 0x27c6, .pid = 0x5584 },
{ .vid = 0x27c6, .pid = 0x55a2 }, { .vid = 0x27c6, .pid = 0x55a2 },
{ .vid = 0x27c6, .pid = 0x55a4 }, { .vid = 0x27c6, .pid = 0x55a4 },

View File

@@ -1,5 +1,5 @@
project('libfprint', [ 'c', 'cpp' ], project('libfprint', [ 'c', 'cpp' ],
version: '1.94.4', version: '1.94.3',
license: 'LGPLv2.1+', license: 'LGPLv2.1+',
default_options: [ default_options: [
'buildtype=debugoptimized', 'buildtype=debugoptimized',

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.

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")

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