@@ -51,28 +51,34 @@ static void remove_transaction_entry(struct fw_card *card, struct fw_transaction
5151 card -> transactions .tlabel_mask &= ~(1ULL << entry -> tlabel );
5252}
5353
54+ // card->transactions.lock must be acquired in advance.
55+ #define find_and_pop_transaction_entry (card , condition ) \
56+ ({ \
57+ struct fw_transaction *iter, *t = NULL; \
58+ list_for_each_entry(iter, &card->transactions.list, link) { \
59+ if (condition) { \
60+ t = iter; \
61+ break; \
62+ } \
63+ } \
64+ if (t && try_cancel_split_timeout(t)) \
65+ remove_transaction_entry(card, t); \
66+ t; \
67+ })
68+
5469static int close_transaction (struct fw_transaction * transaction , struct fw_card * card , int rcode ,
5570 u32 response_tstamp )
5671{
57- struct fw_transaction * t = NULL , * iter ;
72+ struct fw_transaction * t ;
5873
5974 // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
6075 // local destination never runs in any type of IRQ context.
6176 scoped_guard (spinlock_irqsave , & card -> transactions .lock ) {
62- list_for_each_entry (iter , & card -> transactions .list , link ) {
63- if (iter == transaction ) {
64- if (try_cancel_split_timeout (iter )) {
65- remove_transaction_entry (card , iter );
66- t = iter ;
67- }
68- break ;
69- }
70- }
77+ t = find_and_pop_transaction_entry (card , iter == transaction );
78+ if (!t )
79+ return - ENOENT ;
7180 }
7281
73- if (!t )
74- return - ENOENT ;
75-
7682 if (!t -> with_tstamp ) {
7783 t -> callback .without_tstamp (card , rcode , NULL , 0 , t -> callback_data );
7884 } else {
@@ -1102,7 +1108,7 @@ EXPORT_SYMBOL(fw_core_handle_request);
11021108
11031109void fw_core_handle_response (struct fw_card * card , struct fw_packet * p )
11041110{
1105- struct fw_transaction * t = NULL , * iter ;
1111+ struct fw_transaction * t = NULL ;
11061112 u32 * data ;
11071113 size_t data_length ;
11081114 int tcode , tlabel , source , rcode ;
@@ -1144,15 +1150,8 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
11441150 // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
11451151 // local destination never runs in any type of IRQ context.
11461152 scoped_guard (spinlock_irqsave , & card -> transactions .lock ) {
1147- list_for_each_entry (iter , & card -> transactions .list , link ) {
1148- if (iter -> node_id == source && iter -> tlabel == tlabel ) {
1149- if (try_cancel_split_timeout (iter )) {
1150- remove_transaction_entry (card , iter );
1151- t = iter ;
1152- }
1153- break ;
1154- }
1155- }
1153+ t = find_and_pop_transaction_entry (card ,
1154+ iter -> node_id == source && iter -> tlabel == tlabel );
11561155 }
11571156
11581157 trace_async_response_inbound ((uintptr_t )t , card -> index , p -> generation , p -> speed , p -> ack ,
0 commit comments