From 15bea496815f44809559069f715dbf56c6f1cf2d Mon Sep 17 00:00:00 2001 From: Didier Raboud Date: Tue, 15 Jan 2013 18:34:21 +0100 Subject: [PATCH] Backport two upstream hotfixes for uru4000. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both patches are on top of 0.5.0: - uru4000: fix race condition on waiting power up irq - uru4000: fix cancelling of imaging from error callback Thanks-To: Timo Teräs --- debian/patches/series | 5 ++ ...ce-condition-on-waiting-power-up-irq.patch | 87 +++++++++++++++++++ ...elling-of-imaging-from-error-callbac.patch | 45 ++++++++++ 3 files changed, 137 insertions(+) create mode 100644 debian/patches/u7e1646c-uru4000-fix-race-condition-on-waiting-power-up-irq.patch create mode 100644 debian/patches/u8a87ba4-uru4000-fix-cancelling-of-imaging-from-error-callbac.patch diff --git a/debian/patches/series b/debian/patches/series index ad7c2eac..113aa788 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,3 +1,8 @@ +# Upstream backports +u7e1646c-uru4000-fix-race-condition-on-waiting-power-up-irq.patch +u8a87ba4-uru4000-fix-cancelling-of-imaging-from-error-callbac.patch + +# Debian specifics kFreeBSD_FTBFS_add_ETIME_definition.patch udev-rules-creation-add-Debian-specifics.patch Fix-blacklist-handling-in-udev-rules-creation.patch diff --git a/debian/patches/u7e1646c-uru4000-fix-race-condition-on-waiting-power-up-irq.patch b/debian/patches/u7e1646c-uru4000-fix-race-condition-on-waiting-power-up-irq.patch new file mode 100644 index 00000000..94e5b683 --- /dev/null +++ b/debian/patches/u7e1646c-uru4000-fix-race-condition-on-waiting-power-up-irq.patch @@ -0,0 +1,87 @@ +From 7e1646c382bbd6dc21a167bf7f0e45afa5ea217e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= +Date: Tue, 4 Dec 2012 10:50:30 +0200 +Subject: [PATCH] uru4000: fix race condition on waiting power up irq + +It can come before we finish reading the status register on some +cases. Arm the irq handler early, and fix the state machine to +handle early irq properly. + +https://bugs.freedesktop.org/show_bug.cgi?id=57834 +--- + libfprint/drivers/uru4000.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c +index 541245a..07e26a4 100644 +--- a/libfprint/drivers/uru4000.c ++++ b/libfprint/drivers/uru4000.c +@@ -994,16 +994,19 @@ static void init_scanpwr_irq_cb(struct fp_img_dev *dev, int status, + uint16_t type, void *user_data) + { + struct fpi_ssm *ssm = user_data; ++ struct uru4k_dev *urudev = dev->priv; + + if (status) + fpi_ssm_mark_aborted(ssm, status); + else if (type != IRQDATA_SCANPWR_ON) + fp_dbg("ignoring interrupt"); +- else if (ssm->cur_state != INIT_AWAIT_SCAN_POWER) +- fp_err("ignoring scanpwr interrupt due to being in wrong state %d", +- ssm->cur_state); +- else ++ else if (ssm->cur_state != INIT_AWAIT_SCAN_POWER) { ++ fp_dbg("early scanpwr interrupt"); ++ urudev->scanpwr_irq_timeouts = -1; ++ } else { ++ fp_dbg("late scanpwr interrupt"); + fpi_ssm_next_state(ssm); ++ } + } + + static void init_scanpwr_timeout(void *user_data) +@@ -1053,14 +1056,21 @@ static void init_run_state(struct fpi_ssm *ssm) + fpi_ssm_next_state(ssm); + break; + case INIT_POWERUP: ; ++ if (!IRQ_HANDLER_IS_RUNNING(urudev)) { ++ fpi_ssm_mark_aborted(ssm, -EIO); ++ break; ++ } ++ urudev->irq_cb_data = ssm; ++ urudev->irq_cb = init_scanpwr_irq_cb; ++ + struct fpi_ssm *powerupsm = fpi_ssm_new(dev->dev, powerup_run_state, + POWERUP_NUM_STATES); + powerupsm->priv = dev; + fpi_ssm_start_subsm(ssm, powerupsm); + break; + case INIT_AWAIT_SCAN_POWER: +- if (!IRQ_HANDLER_IS_RUNNING(urudev)) { +- fpi_ssm_mark_aborted(ssm, -EIO); ++ if (urudev->scanpwr_irq_timeouts < 0) { ++ fpi_ssm_next_state(ssm); + break; + } + +@@ -1073,13 +1083,12 @@ static void init_run_state(struct fpi_ssm *ssm) + fpi_ssm_mark_aborted(ssm, -ETIME); + break; + } +- +- urudev->irq_cb_data = ssm; +- urudev->irq_cb = init_scanpwr_irq_cb; + break; + case INIT_DONE: +- fpi_timeout_cancel(urudev->scanpwr_irq_timeout); +- urudev->scanpwr_irq_timeout = NULL; ++ if (urudev->scanpwr_irq_timeout) { ++ fpi_timeout_cancel(urudev->scanpwr_irq_timeout); ++ urudev->scanpwr_irq_timeout = NULL; ++ } + urudev->irq_cb_data = NULL; + urudev->irq_cb = NULL; + fpi_ssm_next_state(ssm); +-- +1.7.10.4 + diff --git a/debian/patches/u8a87ba4-uru4000-fix-cancelling-of-imaging-from-error-callbac.patch b/debian/patches/u8a87ba4-uru4000-fix-cancelling-of-imaging-from-error-callbac.patch new file mode 100644 index 00000000..e57d394f --- /dev/null +++ b/debian/patches/u8a87ba4-uru4000-fix-cancelling-of-imaging-from-error-callbac.patch @@ -0,0 +1,45 @@ +From 8a87ba448c62eb14fa51d70ce870dd10b67ba76b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= +Date: Mon, 3 Dec 2012 09:51:27 +0200 +Subject: [PATCH] uru4000: fix cancelling of imaging from error callback + +Call error callback before resetting img_transfer to NULL. This +variable is internally used to detect if we are still in imaging +loop and the call to execute_state_change() needs to be postponed. +Since this is the final thing imaging_complete() we can't reset +img_transfer until just before this call. + +https://bugs.freedesktop.org/show_bug.cgi?id=57829 +--- + libfprint/drivers/uru4000.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c +index 07e26a4..ccaa87f 100644 +--- a/libfprint/drivers/uru4000.c ++++ b/libfprint/drivers/uru4000.c +@@ -789,15 +789,18 @@ static void imaging_complete(struct fpi_ssm *ssm) + int r = ssm->error; + fpi_ssm_free(ssm); + ++ /* Report error before exiting imaging loop - the error handler ++ * can request state change, which needs to be postponed to end of ++ * this function. */ ++ if (r) ++ fpi_imgdev_session_error(dev, r); ++ + g_free(urudev->img_data); + urudev->img_data = NULL; + + libusb_free_transfer(urudev->img_transfer); + urudev->img_transfer = NULL; + +- if (r) +- fpi_imgdev_session_error(dev, r); +- + r = execute_state_change(dev); + if (r) + fpi_imgdev_session_error(dev, r); +-- +1.7.10.4 +