@@ -308,6 +308,7 @@ static void afk_recv_handle_init(struct apple_dcp_afkep *ep, u32 channel,
308308 ch_idx = ep -> num_channels ++ ;
309309 spin_lock_init (& ep -> services [ch_idx ].lock );
310310 ep -> services [ch_idx ].enabled = true;
311+ ep -> services [ch_idx ].torndown = false;
311312 ep -> services [ch_idx ].ops = ops ;
312313 ep -> services [ch_idx ].ep = ep ;
313314 ep -> services [ch_idx ].channel = channel ;
@@ -340,7 +341,12 @@ static void afk_recv_handle_teardown(struct apple_dcp_afkep *ep, u32 channel)
340341
341342 // TODO: think through what locking is necessary
342343 spin_lock_irqsave (& service -> lock , flags );
343- service -> enabled = false;
344+ /*
345+ * teardown must not disable the service since since it may be sent as
346+ * side effect of a COMMAND which for which a reply is expected.
347+ * Seen with DCP's "av" endpoint during the close afk_service_call.
348+ */
349+ service -> torndown = true;
344350 ops = service -> ops ;
345351 spin_unlock_irqrestore (& service -> lock , flags );
346352
@@ -445,6 +451,12 @@ static void afk_recv_handle_std_service(struct apple_dcp_afkep *ep, u32 channel,
445451 ep -> endpoint , channel );
446452 return ;
447453 }
454+ if (service -> torndown ) {
455+ dev_warn (ep -> dcp -> dev ,
456+ "AFK[ep:%02x]: std service notify on torn down service "
457+ "(chan:%u)\n" , ep -> endpoint , channel );
458+ return ;
459+ }
448460
449461 if (type == EPIC_TYPE_NOTIFY && eshdr -> category == EPIC_CAT_NOTIFY ) {
450462 struct epic_std_service_ap_call * call = payload ;
0 commit comments