lib: Add new bus types for drivers

Add a way for drivers to declare they support a bus type other than USB.
We have declarations for SPI and virtual drivers, though there's no
device discovery implemented yet.

https://bugs.freedesktop.org/show_bug.cgi?id=106279

Patch modified from the original by Benjamin Berg <bberg@redhat.com>.
The drivers updates were mainly done using the following spatch:

@drv1@
identifier driver_name;
identifier id_table_var;
@@
struct fp_driver driver_name = {
	...,
-	.id_table = id_table_var,
+	.bus = BUS_TYPE_USB,
+	.id_table.usb = id_table_var,
	...
};
@imgdrv1@
identifier driver_name;
identifier id_table_var;
@@
struct fp_img_driver driver_name = {
	...,
	.driver = {
		...,
-		.id_table = id_table_var,
+		.bus = BUS_TYPE_USB,
+		.id_table.usb = id_table_var,
		...
	},
	...,
};
@imgdrv2@
identifier driver_name;
identifier discover_func;
@@
struct fp_img_driver driver_name = {
	...,
	.driver = {
		...,
-		.discover = discover_func,
+		.usb_discover = discover_func,
		...
	},
	...
};
@idtable1@
identifier drv;
expression x;
@@
	struct fp_driver *drv;
	<...
-	drv->id_table[x]
+	drv->id_table.usb[x]
	...>
@idtable2@
identifier drv;
identifier func;
expression x;
@@
func (..., struct fp_driver *drv, ...)
{
	<...
-	drv->id_table[x]
+	drv->id_table.usb[x]
	...>
}
This commit is contained in:
Bastien Nocera 2018-04-26 16:14:08 +02:00 committed by Benjamin Berg
parent ef2cf067ea
commit 5c0bc90677
29 changed files with 180 additions and 52 deletions

View file

@ -820,7 +820,8 @@ struct fp_img_driver aes1610_driver = {
.id = AES1610_ID,
.name = FP_COMPONENT,
.full_name = "AuthenTec AES1610",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},
.flags = 0,

View file

@ -97,7 +97,8 @@ struct fp_img_driver aes1660_driver = {
.id = AES1660_ID,
.name = FP_COMPONENT,
.full_name = "AuthenTec AES1660",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},
.flags = 0,

View file

@ -862,7 +862,8 @@ struct fp_img_driver aes2501_driver = {
.id = AES2501_ID,
.name = FP_COMPONENT,
.full_name = "AuthenTec AES2501",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},
.flags = 0,

View file

@ -606,7 +606,8 @@ struct fp_img_driver aes2550_driver = {
.id = AES2550_ID,
.name = FP_COMPONENT,
.full_name = "AuthenTec AES2550/AES2810",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},
.flags = 0,

View file

@ -100,7 +100,8 @@ struct fp_img_driver aes2660_driver = {
.id = AES2660_ID,
.name = FP_COMPONENT,
.full_name = "AuthenTec AES2660",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},
.flags = 0,

View file

@ -165,7 +165,8 @@ struct fp_img_driver aes3500_driver = {
.id = AES3500_ID,
.name = FP_COMPONENT,
.full_name = "AuthenTec AES3500",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_PRESS,
},
.flags = 0,

View file

@ -162,7 +162,8 @@ struct fp_img_driver aes4000_driver = {
.id = AES4000_ID,
.name = FP_COMPONENT,
.full_name = "AuthenTec AES4000",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_PRESS,
},
.flags = 0,

View file

@ -82,7 +82,7 @@ static int do_write_regv(struct write_regv_data *wdata, int upper_bound)
data[data_offset++] = regwrite->value;
}
libusb_fill_bulk_transfer(transfer, FP_DEV(wdata->imgdev)->udev, EP_OUT, data,
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev (FP_DEV(wdata->imgdev)), EP_OUT, data,
alloc_size, write_regv_trf_complete, wdata, BULK_TIMEOUT);
r = libusb_submit_transfer(transfer);
if (r < 0) {

View file

@ -973,7 +973,8 @@ struct fp_img_driver elan_driver = {
.id = ELAN_ID,
.name = FP_COMPONENT,
.full_name = "ElanTech Fingerprint Sensor",
.id_table = elan_id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = elan_id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},
.flags = 0,

View file

@ -1481,7 +1481,8 @@ struct fp_img_driver etes603_driver = {
.id = ETES603_ID,
.name = FP_COMPONENT,
.full_name = "EgisTec ES603",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},
.flags = 0,

View file

@ -305,7 +305,8 @@ struct fp_img_driver fdu2000_driver = {
.id = FDU2000_ID,
.name = FP_COMPONENT,
.full_name = "Secugen FDU 2000",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_PRESS,
},
.img_height = RAW_IMAGE_HEIGTH,

View file

@ -1348,9 +1348,10 @@ struct fp_img_driver upeksonly_driver = {
.id = UPEKSONLY_ID,
.name = FP_COMPONENT,
.full_name = "UPEK TouchStrip Sensor-Only",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
.discover = dev_discover,
.usb_discover = dev_discover,
},
.flags = 0,
.img_width = -1,

View file

@ -463,7 +463,8 @@ struct fp_img_driver upektc_driver = {
.id = UPEKTC_ID,
.name = FP_COMPONENT,
.full_name = "UPEK TouchChip/Eikon Touch 300",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_PRESS,
},
.flags = 0,

View file

@ -631,9 +631,10 @@ struct fp_img_driver upektc_img_driver = {
.id = UPEKTC_IMG_ID,
.name = FP_COMPONENT,
.full_name = "Upek TouchChip Fingerprint Coprocessor",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
.discover = discover,
.usb_discover = discover,
},
.flags = 0,
.img_height = IMAGE_HEIGHT,

View file

@ -1424,7 +1424,8 @@ struct fp_driver upekts_driver = {
.id = UPEKTS_ID,
.name = FP_COMPONENT,
.full_name = "UPEK TouchStrip",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
.open = dev_init,
.close = dev_exit,

View file

@ -1431,7 +1431,8 @@ struct fp_img_driver uru4000_driver = {
.id = URU4000_ID,
.name = FP_COMPONENT,
.full_name = "Digital Persona U.are.U 4000/4000B/4500",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_PRESS,
},
.flags = FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE,

View file

@ -360,7 +360,8 @@ struct fp_img_driver vcom5s_driver = {
.id = VCOM5S_ID,
.name = FP_COMPONENT,
.full_name = "Veridicom 5thSense",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_PRESS,
},
.flags = 0,

View file

@ -773,7 +773,8 @@ struct fp_img_driver vfs0050_driver = {
.id = VFS0050_ID,
.name = FP_COMPONENT,
.full_name = "Validity VFS0050",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},

View file

@ -1529,7 +1529,8 @@ struct fp_img_driver vfs101_driver =
.id = VFS101_ID,
.name = FP_COMPONENT,
.full_name = "Validity VFS101",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},

View file

@ -271,7 +271,8 @@ struct fp_img_driver vfs301_driver =
.id = VFS301_ID,
.name = FP_COMPONENT,
.full_name = "Validity VFS301",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},

View file

@ -890,7 +890,8 @@ struct fp_img_driver vfs5011_driver = {
.id = VFS5011_ID,
.name = "vfs5011",
.full_name = "Validity VFS5011",
.id_table = id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = id_table,
.scan_type = FP_SCAN_TYPE_SWIPE,
},

View file

@ -90,8 +90,12 @@ struct fp_dev {
int nr_enroll_stages;
/* FIXME: This will eventually have a bus type */
libusb_device_handle *udev;
enum fp_bus_type bus;
union {
libusb_device_handle *usb;
const char *virtual_env;
int i2c;
} device;
/* read-only to drivers */
struct fp_print_data *verify_data;
@ -156,7 +160,13 @@ struct fp_img_dev {
/* fp_dscv_dev structure definition */
struct fp_dscv_dev {
struct libusb_device *udev;
enum fp_bus_type bus;
union {
struct libusb_device *usb;
const char *virtual_env;
char *spi_path;
} desc;
struct fp_driver *drv;
unsigned long driver_data;
uint32_t devtype;

View file

@ -66,7 +66,6 @@ API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb call
{
struct fp_driver *drv;
struct fp_dev *dev;
libusb_device_handle *udevh;
int r;
g_return_val_if_fail(ddev != NULL, -ENODEV);
@ -75,20 +74,32 @@ API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb call
drv = ddev->drv;
G_DEBUG_HERE();
r = libusb_open(ddev->udev, &udevh);
if (r < 0) {
fp_err("usb_open failed, error %d", r);
return r;
}
dev = g_malloc0(sizeof(*dev));
dev->drv = drv;
dev->udev = udevh;
dev->bus = ddev->bus;
dev->__enroll_stage = -1;
dev->state = DEV_STATE_INITIALIZING;
dev->open_cb = callback;
dev->open_cb_data = user_data;
switch (ddev->bus) {
case BUS_TYPE_USB:
r = libusb_open(ddev->desc.usb, &dev->device.usb);
if (r < 0) {
fp_err("usb_open failed, error %d", r);
g_free (dev);
return r;
}
break;
case BUS_TYPE_SPI:
/* TODO: Implement */
break;
case BUS_TYPE_VIRTUAL:
dev->device.virtual_env = ddev->desc.virtual_env;
break;
}
if (!drv->open) {
fpi_drvcb_open_complete(dev, 0);
return 0;
@ -98,7 +109,14 @@ API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb call
r = drv->open(dev, ddev->driver_data);
if (r) {
fp_err("device initialisation failed, driver=%s", drv->name);
libusb_close(udevh);
switch (ddev->bus) {
case BUS_TYPE_USB:
libusb_close(dev->device.usb);
case BUS_TYPE_SPI:
case BUS_TYPE_VIRTUAL:
/* Nothing to do (this might change for SPI) */
break;
}
g_free(dev);
}
@ -112,7 +130,16 @@ void fpi_drvcb_close_complete(struct fp_dev *dev)
BUG_ON(dev->state != DEV_STATE_DEINITIALIZING);
dev->state = DEV_STATE_DEINITIALIZED;
fpi_timeout_cancel_all_for_dev(dev);
libusb_close(dev->udev);
switch (dev->bus) {
case BUS_TYPE_USB:
libusb_close(dev->device.usb);
case BUS_TYPE_SPI:
case BUS_TYPE_VIRTUAL:
/* Nothing to do (this might change for SPI) */
break;
}
if (dev->close_cb)
dev->close_cb(dev, dev->close_cb_data);
g_free(dev);

View file

@ -207,10 +207,13 @@ static struct fp_driver *find_supporting_usb_driver(libusb_device *udev,
uint32_t type = 0;
const struct usb_id *id;
for (id = drv->id_table; id->vendor; id++) {
if (drv->bus != BUS_TYPE_USB)
continue;
for (id = drv->id_table.usb; id->vendor; id++) {
if (dsc.idVendor == id->vendor && dsc.idProduct == id->product) {
if (drv->discover) {
int r = drv->discover(&dsc, &type);
if (drv->usb_discover) {
int r = drv->usb_discover(&dsc, &type);
if (r < 0)
fp_err("%s discover failed, code %d", drv->name, r);
if (r <= 0)
@ -260,7 +263,8 @@ static struct fp_dscv_dev *discover_usb_dev(libusb_device *udev)
ddev = g_malloc0(sizeof(*ddev));
ddev->drv = drv;
ddev->udev = udev;
ddev->bus = BUS_TYPE_USB;
ddev->desc.usb = udev;
ddev->driver_data = usb_id->driver_data;
ddev->devtype = devtype;
return ddev;
@ -330,7 +334,17 @@ API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs)
return;
for (i = 0; devs[i]; i++) {
libusb_unref_device(devs[i]->udev);
switch (devs[i]->bus) {
case BUS_TYPE_USB:
libusb_unref_device(devs[i]->desc.usb);
break;
case BUS_TYPE_SPI:
g_free(devs[i]->desc.spi_path);
break;
case BUS_TYPE_VIRTUAL:
/* Nothing to do */
break;
}
g_free(devs[i]);
}
g_free(devs);

View file

@ -67,16 +67,37 @@ enum fp_driver_type {
DRIVER_IMAGING = 1,
};
/**
* fp_bus_type:
* @BUS_TYPE_USB: USB device
* @BUS_TYPE_SPI: SPI device
* @BUS_TYPE_VIRTUAL: Virtual test bus
*
* The bus type of the device/driver.
*/
enum fp_bus_type {
BUS_TYPE_USB,
BUS_TYPE_SPI,
BUS_TYPE_VIRTUAL
};
struct fp_driver {
const uint16_t id;
const char *name;
const char *full_name;
const struct usb_id * const id_table;
enum fp_bus_type bus;
union {
const struct usb_id * const usb;
const char * const *i2c;
const char * virtual_envvar;
} id_table;
enum fp_driver_type type;
enum fp_scan_type scan_type;
/* Device operations */
int (*discover)(struct libusb_device_descriptor *dsc, uint32_t *devtype);
int (*usb_discover)(struct libusb_device_descriptor *dsc, uint32_t *devtype);
int (*open)(struct fp_dev *dev, unsigned long driver_data);
void (*close)(struct fp_dev *dev);
int (*enroll_start)(struct fp_dev *dev);

View file

@ -114,7 +114,34 @@ FP_INSTANCE_DATA (struct fp_dev *dev)
libusb_device_handle *
fpi_dev_get_usb_dev(struct fp_dev *dev)
{
return dev->udev;
g_assert (dev->bus == BUS_TYPE_USB);
return dev->device.usb;
}
/**
* fpi_dev_get_virtual_env:
* @dev: a struct #fp_dev
*
* Returns the value of the environment variable that is assicated with
* the virtual device.
*
* Returns: the value of the environment variable
*/
const char *
fpi_dev_get_virtual_env(struct fp_dev *dev)
{
g_assert (dev->bus == BUS_TYPE_VIRTUAL);
return dev->device.virtual_env;
}
int
fpi_dev_get_spi_dev(struct fp_dev *dev)
{
g_assert (dev->bus == BUS_TYPE_SPI);
return dev->device.i2c;
}
/**

View file

@ -40,6 +40,8 @@ void fp_dev_set_instance_data (struct fp_dev *dev,
void *FP_INSTANCE_DATA (struct fp_dev *dev);
libusb_device_handle *fpi_dev_get_usb_dev(struct fp_dev *dev);
const char *fpi_dev_get_virtual_env(struct fp_dev *dev);
int fpi_dev_get_spi_dev(struct fp_dev *dev);
void fpi_dev_set_nr_enroll_stages(struct fp_dev *dev,
int nr_enroll_stages);
struct fp_print_data *fpi_dev_get_verify_data(struct fp_dev *dev);

View file

@ -31,10 +31,11 @@ static GList *insert_driver (GList *list,
{
int i;
for (i = 0; driver->id_table[i].vendor != 0; i++) {
for (i = 0; driver->id_table.usb[i].vendor != 0; i++) {
char *key;
key = g_strdup_printf ("%04x:%04x", driver->id_table[i].vendor, driver->id_table[i].product);
key = g_strdup_printf ("%04x:%04x", driver->id_table.usb[i].vendor,
driver->id_table.usb[i].product);
if (g_hash_table_lookup (printed, key) != NULL) {
g_free (key);

View file

@ -40,7 +40,8 @@ static const struct usb_id blacklist_id_table[] = {
};
struct fp_driver whitelist = {
.id_table = whitelist_id_table,
.bus = BUS_TYPE_USB,
.id_table.usb = whitelist_id_table,
.full_name = "Hardcoded whitelist"
};
@ -52,13 +53,13 @@ static void print_driver (struct fp_driver *driver)
num_printed = 0;
for (i = 0; driver->id_table[i].vendor != 0; i++) {
for (i = 0; driver->id_table.usb[i].vendor != 0; i++) {
char *key;
blacklist = 0;
for (j = 0; blacklist_id_table[j].vendor != 0; j++) {
if (driver->id_table[i].vendor == blacklist_id_table[j].vendor &&
driver->id_table[i].product == blacklist_id_table[j].product) {
if (driver->id_table.usb[i].vendor == blacklist_id_table[j].vendor &&
driver->id_table.usb[i].product == blacklist_id_table[j].product) {
blacklist = 1;
break;
}
@ -66,7 +67,8 @@ static void print_driver (struct fp_driver *driver)
if (blacklist)
continue;
key = g_strdup_printf ("%04x:%04x", driver->id_table[i].vendor, driver->id_table[i].product);
key = g_strdup_printf ("%04x:%04x", driver->id_table.usb[i].vendor,
driver->id_table.usb[i].product);
if (g_hash_table_lookup (printed, key) != NULL) {
g_free (key);
@ -78,8 +80,12 @@ static void print_driver (struct fp_driver *driver)
if (num_printed == 0)
printf ("# %s\n", driver->full_name);
printf ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ATTRS{dev}==\"*\", TEST==\"power/control\", ATTR{power/control}=\"auto\"\n", driver->id_table[i].vendor, driver->id_table[i].product);
printf ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ENV{LIBFPRINT_DRIVER}=\"%s\"\n", driver->id_table[i].vendor, driver->id_table[i].product, driver->full_name);
printf ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ATTRS{dev}==\"*\", TEST==\"power/control\", ATTR{power/control}=\"auto\"\n",
driver->id_table.usb[i].vendor,
driver->id_table.usb[i].product);
printf ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ENV{LIBFPRINT_DRIVER}=\"%s\"\n",
driver->id_table.usb[i].vendor,
driver->id_table.usb[i].product, driver->full_name);
num_printed++;
}