[PATCH 1/2] firewire: core: don't disable error work for transaction

From: Takashi Sakamoto

Date: Sat Oct 17 2026 - 11:33:58 EST


The error callback work is scheduled only when the transaction instance
is no longer on the pending list. Therefore, iterating over the list to
cancel the work is pointless.

Remove the code that cancels the work while iterating over the pending
list. Once scheduled, the work can run and invoke the error callback
without being cancelled.

Signed-off-by: Takashi Sakamoto <o-takashi@xxxxxxxxxxxxx>
---
drivers/firewire/core-transaction.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 48558857e726..029bd9cdc570 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -44,7 +44,7 @@ static int try_cancel_split_timeout(struct fw_transaction *t)
lockdep_assert_held(&t->card->transactions.lock);

if (t->is_split_transaction)
- return timer_delete(&t->split_timeout_timer) || disable_work(&t->error_work);
+ return timer_delete(&t->split_timeout_timer);
else
return 1;
}
@@ -146,16 +146,22 @@ __must_not_hold(&card->transactions.lock)
transaction->response_timestamp = cycle_time_to_ohci_tstamp(curr_cycle_time);
transaction->rcode = RCODE_CANCELLED;

- enable_and_queue_work(card->async_wq, &transaction->error_work);
+ queue_work(card->async_wq, &transaction->error_work);

return 0;
}
EXPORT_SYMBOL(fw_cancel_transaction);

+// Ensure that the transaction is not on the pending list when scheduling this work. Cancelling
+// the work after scheduling makes no sense, as the initiator must be notified of the transaction
+// result.
static void error_callback_work(struct work_struct *work)
{
struct fw_transaction *t = from_work(t, work, error_work);

+ // To detect programming mistakes.
+ WARN_ON(!list_empty(&t->link));
+
invoke_callback(t, t->rcode, t->response_timestamp, NULL, 0);
}

@@ -414,6 +420,7 @@ __must_not_hold(&card->transactions.lock)
t->with_tstamp = with_tstamp;
t->callback_data = callback_data;
INIT_WORK(&t->error_work, error_callback_work);
+ INIT_LIST_HEAD(&t->link);

/*
* Allocate tlabel from the bitmap and put the transaction on
--
2.53.0