Conversation

Takashi Sakamoto (坂本 貴史)

Hm.

$ git show
commit ba003f0c08ead39934425cb3a70e0e8f83ed7a5b (HEAD -> topic/cdev/iso-resource-once-rework)
Author: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date:   Mon Aug 24 23:12:18 2026 +0900

    firewire: ohci: don't handle AT request/response packets in caller's context
    
    It is inconvenient to handle AT request/response packets in the context of
    __fw_send_request() call, since it could be any type of IRQ contexts. In
    the case, the address handler implementation should take care of the lock
    type.

diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index e947227e..1195eab1 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1535,11 +1535,23 @@ static void handle_local_lock(struct fw_ohci *ohci,
        fw_core_handle_response(&ohci->card, &response);
 }
 
-static void handle_local_request(struct at_context *ctx, struct fw_packet *packet)
+struct local_at_packet {
+       struct work_struct work;
+       struct at_context *ctx;
+       struct fw_packet *p;
+};
+
+static void local_at_run(struct work_struct *work)
 {
+       struct local_at_packet *local_packet = from_work(local_packet, work, work);
+       struct fw_packet *packet = local_packet->p;
+       struct at_context *ctx = local_packet->ctx;
        struct fw_ohci *ohci = ctx->context.ohci;
        u64 offset, csr;
 
+       // Timestamping on behalf of the hardware.
+       packet->timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci));
+
        if (ctx == &ohci->at_request_ctx) {
                packet->ack = ACK_PENDING;
                packet->callback(packet, &ohci->card, packet->ack);
@@ -1570,6 +1582,8 @@ static void handle_local_request(struct at_context *ctx, struct fw_packet *packe
                packet->ack = ACK_COMPLETE;
                packet->callback(packet, &ohci->card, packet->ack);
        }
+
+       kfree(local_packet);
 }
 
 static void at_context_transmit(struct at_context *ctx, struct fw_packet *packet)
@@ -1584,10 +1598,18 @@ static void at_context_transmit(struct at_context *ctx, struct fw_packet *packet
            ohci->generation == packet->generation) {
                spin_unlock_irqrestore(&ohci->lock, flags);
 
-               // Timestamping on behalf of the hardware.
-               packet->timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci));
+               struct local_at_packet *local_packet = kmalloc_obj(*local_packet);
+
+               // TODO:
+               if (!local_packet)
+                       return;
+
+               INIT_WORK(&local_packet->work, local_at_run);
+               local_packet->ctx = ctx;
+               local_packet->p = packet;
+
+               queue_work(ohci->card.async_wq, &local_packet->work);
 
-               handle_local_request(ctx, packet);
                return;
        }
 
0
0
0