* [PATCH 1/6] firewire: core: use spinlock_irqsave() appropriately for transaction list lock
2026-10-08 23:44 [PATCH 0/6] firewire: core: make execution context assumptions explicit Takashi Sakamoto
@ 2026-10-08 23:44 ` Takashi Sakamoto
2026-10-09 0:22 ` Takashi Sakamoto
2026-10-08 23:44 ` [PATCH 2/6] firewire: core: add might_sleep() checks Takashi Sakamoto
` (4 subsequent siblings)
5 siblings, 1 reply; 8+ messages in thread
From: Takashi Sakamoto @ 2026-10-08 23:44 UTC (permalink / raw)
To: linux1394-devel; +Cc: linux-kernel
The transaction.lock in the fw_card structure protects the transaction
list from concurrent access. The list is mostly accessed from process
context, with two exceptions: split_transaction_timeout_callback()
acquires the lock in softIRQ context for the timer wheel, and
__fw_send_request() acquires it in the caller's context, which can
include hardIRQ context.
Use spinlock_irq() in process context and spinlock_irqsave() in the other
contexts. Update the relevant scoped_guard() invocations accordingly and
remove the unnecessary comments.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
drivers/firewire/core-transaction.c | 27 +++++----------------------
1 file changed, 5 insertions(+), 22 deletions(-)
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index a0379fc3e60e..39715cf79ab9 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -69,9 +69,7 @@ void fw_cancel_pending_transactions(struct fw_card *card)
struct fw_transaction *t, *tmp;
LIST_HEAD(pending_list);
- // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
- // local destination never runs in any type of IRQ context.
- scoped_guard(spinlock_irqsave, &card->transactions.lock) {
+ scoped_guard(spinlock_irq, &card->transactions.lock) {
list_for_each_entry_safe(t, tmp, &card->transactions.list, link) {
if (try_cancel_split_timeout(t))
list_move(&t->link, &pending_list);
@@ -121,10 +119,7 @@ int fw_cancel_transaction(struct fw_card *card, struct fw_transaction *transacti
// If the request packet has already been sent, we need to see if the transaction is still
// pending and remove it in that case (e.g. the split transaction).
- //
- // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
- // local destination never runs in any type of IRQ context.
- scoped_guard(spinlock_irqsave, &card->transactions.lock) {
+ scoped_guard(spinlock_irq, &card->transactions.lock) {
if (!find_and_pop_transaction_entry(card, iter == transaction))
return -ENOENT;
}
@@ -204,9 +199,7 @@ static void transmit_complete_callback(struct fw_packet *packet,
delta = card->split_timeout.jiffies;
}
- // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
- // local destination never runs in any type of IRQ context.
- scoped_guard(spinlock_irqsave, &card->transactions.lock)
+ scoped_guard(spinlock_irq, &card->transactions.lock)
start_split_transaction_timeout(t, delta);
return;
}
@@ -230,9 +223,7 @@ static void transmit_complete_callback(struct fw_packet *packet,
break;
}
- // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
- // local destination never runs in any type of IRQ context.
- scoped_guard(spinlock_irqsave, &card->transactions.lock) {
+ scoped_guard(spinlock_irq, &card->transactions.lock) {
if (!find_and_pop_transaction_entry(card, iter == t))
return;
}
@@ -399,8 +390,6 @@ void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode
* the list while holding the card spinlock.
*/
- // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
- // local destination never runs in any type of IRQ context.
scoped_guard(spinlock_irqsave, &card->transactions.lock)
tlabel = allocate_tlabel(card);
if (tlabel < 0) {
@@ -423,16 +412,12 @@ void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode
timer_setup(&t->split_timeout_timer, split_transaction_timeout_callback, 0);
t->packet.callback = transmit_complete_callback;
- // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
- // local destination never runs in any type of IRQ context.
scoped_guard(spinlock_irqsave, &card->lock) {
// The node_id field of fw_card can be updated when handling SelfIDComplete.
fw_fill_request(&t->packet, tcode, t->tlabel, destination_id, card->node_id,
generation, speed, offset, payload, length);
}
- // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
- // local destination never runs in any type of IRQ context.
scoped_guard(spinlock_irqsave, &card->transactions.lock)
list_add_tail(&t->link, &card->transactions.list);
@@ -1176,9 +1161,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
break;
}
- // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
- // local destination never runs in any type of IRQ context.
- scoped_guard(spinlock_irqsave, &card->transactions.lock) {
+ scoped_guard(spinlock_irq, &card->transactions.lock) {
t = find_and_pop_transaction_entry(card,
iter->node_id == source && iter->tlabel == tlabel);
}
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 1/6] firewire: core: use spinlock_irqsave() appropriately for transaction list lock
2026-10-08 23:44 ` [PATCH 1/6] firewire: core: use spinlock_irqsave() appropriately for transaction list lock Takashi Sakamoto
@ 2026-10-09 0:22 ` Takashi Sakamoto
0 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2026-10-09 0:22 UTC (permalink / raw)
To: linux1394-devel; +Cc: linux-kernel
On Fri, Oct 09, 2026 at 08:44:27AM +0900, Takashi Sakamoto wrote:
> The transaction.lock in the fw_card structure protects the transaction
> list from concurrent access. The list is mostly accessed from process
> context, with two exceptions: split_transaction_timeout_callback()
> acquires the lock in softIRQ context for the timer wheel, and
> __fw_send_request() acquires it in the caller's context, which can
> include hardIRQ context.
>
> Use spinlock_irq() in process context and spinlock_irqsave() in the other
> contexts. Update the relevant scoped_guard() invocations accordingly and
> remove the unnecessary comments.
>
> Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
> ---
> drivers/firewire/core-transaction.c | 27 +++++----------------------
> 1 file changed, 5 insertions(+), 22 deletions(-)
I realized that the change is incorrect in the way to use these spin_lock
variants. Drop this from the series.
Regards
Takashi Sakamoto
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/6] firewire: core: add might_sleep() checks
2026-10-08 23:44 [PATCH 0/6] firewire: core: make execution context assumptions explicit Takashi Sakamoto
2026-10-08 23:44 ` [PATCH 1/6] firewire: core: use spinlock_irqsave() appropriately for transaction list lock Takashi Sakamoto
@ 2026-10-08 23:44 ` Takashi Sakamoto
2026-10-08 23:44 ` [PATCH 3/6] firewire: core: use sparse annotations and lockdep checks for transaction lock Takashi Sakamoto
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2026-10-08 23:44 UTC (permalink / raw)
To: linux1394-devel; +Cc: linux-kernel
Some functions are now guaranteed to run in process context.
Add might_sleep() calls to these functions to document and check this
requirement.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
drivers/firewire/core-transaction.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 39715cf79ab9..ac7a9bde6fef 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -112,6 +112,9 @@ void fw_cancel_pending_transactions(struct fw_card *card)
*/
int fw_cancel_transaction(struct fw_card *card, struct fw_transaction *transaction)
{
+ // Allow the call of struct fw_card_driver.cancel_packet() to wait any event.
+ might_sleep();
+
// Cancel the packet transmission if it's still queued. That will schedule the packet
// transmission callback which cancels the transaction.
if (card->driver->cancel_packet(card, &transaction->packet) == 0)
@@ -473,6 +476,9 @@ int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
struct transaction_callback_data d;
struct fw_transaction t;
+ // Due to the call of wait_for_completion().
+ might_sleep();
+
timer_setup_on_stack(&t.split_timeout_timer, NULL, 0);
init_completion(&d.done);
d.payload = payload;
@@ -509,6 +515,9 @@ void fw_send_phy_config(struct fw_card *card,
long timeout = msecs_to_jiffies(100);
u32 data = 0;
+ // Due to the call of wait_for_completion_timeout().
+ might_sleep();
+
phy_packet_set_packet_identifier(&data, PHY_PACKET_PACKET_IDENTIFIER_PHY_CONFIG);
if (node_id != FW_PHY_CONFIG_NO_NODE_ID) {
@@ -682,6 +691,9 @@ EXPORT_SYMBOL(fw_core_add_address_handler);
*/
void fw_core_remove_address_handler(struct fw_address_handler *handler)
{
+ // Due to synchronize_rcu().
+ might_sleep();
+
scoped_guard(spinlock, &address_handler_list_lock)
list_del_rcu(&handler->link);
@@ -1089,6 +1101,10 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
unsigned long long offset;
unsigned int tcode;
+ // Allow the call of allocate_request() to perform object allocation with GFP_KERNEL,
+ // as well as the address handlers to work with the sleepable lock primitives.
+ might_sleep();
+
if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
return;
@@ -1127,6 +1143,9 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
size_t data_length;
int tcode, tlabel, source, rcode;
+ // Allow the call of struct fw_card_driver.cancel_packet() to wait any event.
+ might_sleep();
+
tcode = async_header_get_tcode(p->header);
tlabel = async_header_get_tlabel(p->header);
source = async_header_get_source(p->header);
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3/6] firewire: core: use sparse annotations and lockdep checks for transaction lock
2026-10-08 23:44 [PATCH 0/6] firewire: core: make execution context assumptions explicit Takashi Sakamoto
2026-10-08 23:44 ` [PATCH 1/6] firewire: core: use spinlock_irqsave() appropriately for transaction list lock Takashi Sakamoto
2026-10-08 23:44 ` [PATCH 2/6] firewire: core: add might_sleep() checks Takashi Sakamoto
@ 2026-10-08 23:44 ` Takashi Sakamoto
2026-10-08 23:44 ` [PATCH 4/6] firewire: core: use sparse annotations and lockdep checks for topology map lock Takashi Sakamoto
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2026-10-08 23:44 UTC (permalink / raw)
To: linux1394-devel; +Cc: linux-kernel
The spinlock protects the list of pending transactions and the transaction
label.
Add sparse annotations and lockdep checks for this lock.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
drivers/firewire/core-transaction.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index ac7a9bde6fef..0c492e4af971 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -38,16 +38,21 @@
/* returns 0 if the split timeout handler is already running */
static int try_cancel_split_timeout(struct fw_transaction *t)
+__must_hold(&t->card->transactions.lock)
{
+ lockdep_assert_held(&t->card->transactions.lock);
+
if (t->is_split_transaction)
return timer_delete(&t->split_timeout_timer) || disable_work(&t->error_work);
else
return 1;
}
-// card->transactions.lock must be acquired in advance.
static void remove_transaction_entry(struct fw_card *card, struct fw_transaction *entry)
+__must_hold(&card->transactions.lock)
{
+ lockdep_assert_held(&card->transactions.lock);
+
list_del_init(&entry->link);
card->transactions.tlabel_mask &= ~(1ULL << entry->tlabel);
}
@@ -65,10 +70,13 @@ static void invoke_callback(struct fw_transaction *t, int rcode, u32 response_ts
// Must be called without holding card->transactions.lock.
void fw_cancel_pending_transactions(struct fw_card *card)
+__must_not_hold(&card->transactions.lock)
{
struct fw_transaction *t, *tmp;
LIST_HEAD(pending_list);
+ lockdep_assert_not_held(&card->transactions.lock);
+
scoped_guard(spinlock_irq, &card->transactions.lock) {
list_for_each_entry_safe(t, tmp, &card->transactions.list, link) {
if (try_cancel_split_timeout(t))
@@ -111,7 +119,10 @@ void fw_cancel_pending_transactions(struct fw_card *card)
* pending transaction.
*/
int fw_cancel_transaction(struct fw_card *card, struct fw_transaction *transaction)
+__must_not_hold(&card->transactions.lock)
{
+ lockdep_assert_not_held(&card->transactions.lock);
+
// Allow the call of struct fw_card_driver.cancel_packet() to wait any event.
might_sleep();
@@ -156,10 +167,13 @@ static void schedule_error_callback(struct fw_transaction *t, int rcode, u32 res
}
static void split_transaction_timeout_callback(struct timer_list *timer)
+__must_not_hold(&card->transactions.lock)
{
struct fw_transaction *t = timer_container_of(t, timer, split_timeout_timer);
struct fw_card *card = t->card;
+ lockdep_assert_not_held(&card->transactions.lock);
+
scoped_guard(spinlock_irqsave, &card->transactions.lock) {
if (list_empty(&t->link))
return;
@@ -169,9 +183,11 @@ static void split_transaction_timeout_callback(struct timer_list *timer)
schedule_error_callback(t, RCODE_CANCELLED, t->split_timeout_cycle);
}
-// card->transactions.lock should be acquired in advance for the linked list.
static void start_split_transaction_timeout(struct fw_transaction *t, unsigned int delta)
+__must_hold(&t->card->transactions.lock)
{
+ lockdep_assert_held(&t->card->transactions.lock);
+
if (list_empty(&t->link) || WARN_ON(t->is_split_transaction))
return;
@@ -184,10 +200,13 @@ static u32 compute_split_timeout_timestamp(struct fw_card *card, u32 request_tim
static void transmit_complete_callback(struct fw_packet *packet,
struct fw_card *card, int status)
+__must_not_hold(&card->transactions.lock)
{
struct fw_transaction *t =
container_of(packet, struct fw_transaction, packet);
+ lockdep_assert_not_held(&card->transactions.lock);
+
trace_async_request_outbound_complete((uintptr_t)t, card->index, packet->generation,
packet->speed, status, packet->timestamp);
@@ -379,9 +398,12 @@ void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode
int destination_id, int generation, int speed, unsigned long long offset,
void *payload, size_t length, union fw_transaction_callback callback,
bool with_tstamp, void *callback_data)
+__must_not_hold(&card->transactions.lock)
{
int tlabel;
+ lockdep_assert_not_held(&card->transactions.lock);
+
t->card = card;
t->callback = callback;
t->with_tstamp = with_tstamp;
@@ -1137,12 +1159,15 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
EXPORT_SYMBOL(fw_core_handle_request);
void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
+__must_not_hold(&card->transactions.lock)
{
struct fw_transaction *t = NULL;
u32 *data;
size_t data_length;
int tcode, tlabel, source, rcode;
+ lockdep_assert_not_held(&card->transactions.lock);
+
// Allow the call of struct fw_card_driver.cancel_packet() to wait any event.
might_sleep();
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 4/6] firewire: core: use sparse annotations and lockdep checks for topology map lock
2026-10-08 23:44 [PATCH 0/6] firewire: core: make execution context assumptions explicit Takashi Sakamoto
` (2 preceding siblings ...)
2026-10-08 23:44 ` [PATCH 3/6] firewire: core: use sparse annotations and lockdep checks for transaction lock Takashi Sakamoto
@ 2026-10-08 23:44 ` Takashi Sakamoto
2026-10-08 23:44 ` [PATCH 5/6] firewire: core: use sparse annotations and lockdep checks for split timeout lock Takashi Sakamoto
2026-10-08 23:44 ` [PATCH 6/6] firewire: core: narrow the card lock scope when accessing node_id Takashi Sakamoto
5 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2026-10-08 23:44 UTC (permalink / raw)
To: linux1394-devel; +Cc: linux-kernel
The spinlock protects the topology map from concurrent access.
Add sparse annotations and lockdep checks for this lock.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
drivers/firewire/core-topology.c | 3 +++
drivers/firewire/core-transaction.c | 3 +++
2 files changed, 6 insertions(+)
diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c
index ee6b54f89859..512b7e4473af 100644
--- a/drivers/firewire/core-topology.c
+++ b/drivers/firewire/core-topology.c
@@ -474,9 +474,12 @@ static void update_topology_map(__be32 *buffer, size_t buffer_size, int root_nod
void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
int self_id_count, u32 *self_ids, bool bm_abdicate)
+__must_not_hold(&card->topology_map.lock)
{
struct fw_node *local_node;
+ lockdep_assert_not_held(&card->topology_map.lock);
+
trace_bus_reset_handle(card->index, generation, node_id, bm_abdicate, self_ids, self_id_count);
scoped_guard(spinlock, &card->lock) {
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 0c492e4af971..4dec03340ae6 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -1263,9 +1263,12 @@ static void handle_topology_map(struct fw_card *card, struct fw_request *request
int tcode, int destination, int source, int generation,
unsigned long long offset, void *payload, size_t length,
void *callback_data)
+__must_not_hold(&card->topology_map.lock)
{
int start;
+ lockdep_assert_not_held(&card->topology_map.lock);
+
if (!tcode_is_read_request(tcode)) {
fw_send_response(card, request, RCODE_TYPE_ERROR);
return;
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 5/6] firewire: core: use sparse annotations and lockdep checks for split timeout lock
2026-10-08 23:44 [PATCH 0/6] firewire: core: make execution context assumptions explicit Takashi Sakamoto
` (3 preceding siblings ...)
2026-10-08 23:44 ` [PATCH 4/6] firewire: core: use sparse annotations and lockdep checks for topology map lock Takashi Sakamoto
@ 2026-10-08 23:44 ` Takashi Sakamoto
2026-10-08 23:44 ` [PATCH 6/6] firewire: core: narrow the card lock scope when accessing node_id Takashi Sakamoto
5 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2026-10-08 23:44 UTC (permalink / raw)
To: linux1394-devel; +Cc: linux-kernel
The spinlock protects parameters related to split transaction timeouts.
Add sparse annotations and lockdep checks for this lock.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
drivers/firewire/core-transaction.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 4dec03340ae6..7d512defdeb3 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -200,11 +200,13 @@ static u32 compute_split_timeout_timestamp(struct fw_card *card, u32 request_tim
static void transmit_complete_callback(struct fw_packet *packet,
struct fw_card *card, int status)
+__must_not_hold(&card->split_timeout.lock)
__must_not_hold(&card->transactions.lock)
{
struct fw_transaction *t =
container_of(packet, struct fw_transaction, packet);
+ lockdep_assert_not_held(&card->split_timeout.lock);
lockdep_assert_not_held(&card->transactions.lock);
trace_async_request_outbound_complete((uintptr_t)t, card->index, packet->generation,
@@ -878,11 +880,14 @@ __must_hold(&card->split_timeout.lock)
static struct fw_request *allocate_request(struct fw_card *card,
struct fw_packet *p)
+__must_not_hold(&card->split_timeout.lock)
{
struct fw_request *request;
u32 *data, length;
int request_tcode;
+ lockdep_assert_not_held(&card->split_timeout.lock);
+
request_tcode = async_header_get_tcode(p->header);
switch (request_tcode) {
case TCODE_WRITE_QUADLET_REQUEST:
@@ -1301,6 +1306,8 @@ __must_hold(&card->split_timeout.lock)
{
unsigned int cycles;
+ lockdep_assert_held(&card->split_timeout.lock);
+
cycles = card->split_timeout.hi * 8000 + (card->split_timeout.lo >> 19);
/* minimum per IEEE 1394, maximum which doesn't overflow OHCI */
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 6/6] firewire: core: narrow the card lock scope when accessing node_id
2026-10-08 23:44 [PATCH 0/6] firewire: core: make execution context assumptions explicit Takashi Sakamoto
` (4 preceding siblings ...)
2026-10-08 23:44 ` [PATCH 5/6] firewire: core: use sparse annotations and lockdep checks for split timeout lock Takashi Sakamoto
@ 2026-10-08 23:44 ` Takashi Sakamoto
5 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2026-10-08 23:44 UTC (permalink / raw)
To: linux1394-devel; +Cc: linux-kernel
When preparing the request subaction for an asynchronous transaction,
the node_id field in the fw_card structure is accessed under the
card-level spinlock. However, the lock is held across a call to a helper
function, unnecessarily extending the critical section.
Narrow the critical section to cover only the access to node_id.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
drivers/firewire/core-transaction.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 7d512defdeb3..4da4686fb28c 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -439,11 +439,12 @@ __must_not_hold(&card->transactions.lock)
timer_setup(&t->split_timeout_timer, split_transaction_timeout_callback, 0);
t->packet.callback = transmit_complete_callback;
- scoped_guard(spinlock_irqsave, &card->lock) {
- // The node_id field of fw_card can be updated when handling SelfIDComplete.
- fw_fill_request(&t->packet, tcode, t->tlabel, destination_id, card->node_id,
- generation, speed, offset, payload, length);
- }
+ // The node_id field of fw_card can be updated when handling SelfIDComplete.
+ int node_id;
+ scoped_guard(spinlock_irqsave, &card->lock)
+ node_id = card->node_id;
+ fw_fill_request(&t->packet, tcode, t->tlabel, destination_id, node_id, generation, speed,
+ offset, payload, length);
scoped_guard(spinlock_irqsave, &card->transactions.lock)
list_add_tail(&t->link, &card->transactions.list);
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread