Skip to content

Commit 57e6d9f

Browse files
committed
firewire: ohci: use workqueue to handle events of AR request/response contexts
This commit adds a work item to handle events of 1394 OHCI AR request/response contexts, and queues the item to the specific workqueue. The call of struct fw_address_handler.address_callback() is done in the workqueue when receiving any requests from the remove nodes. Additionally, the call of struct fw_packet.callback() is done in the workqueue too when receiving acknowledge to the asynchronous packet for the response subaction of split transaction to the remote nodes. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Sakamoto <[email protected]>
1 parent 72bf144 commit 57e6d9f

File tree

2 files changed

+15
-19
lines changed

2 files changed

+15
-19
lines changed

drivers/firewire/core-transaction.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -557,9 +557,10 @@ const struct fw_address_region fw_unit_space_region =
557557
*
558558
* region->start, ->end, and handler->length have to be quadlet-aligned.
559559
*
560-
* When a request is received that falls within the specified address range,
561-
* the specified callback is invoked. The parameters passed to the callback
562-
* give the details of the particular request.
560+
* When a request is received that falls within the specified address range, the specified callback
561+
* is invoked. The parameters passed to the callback give the details of the particular request.
562+
* The callback is invoked in the workqueue context in most cases. However, if the request is
563+
* initiated by the local node, the callback is invoked in the initiator's context.
563564
*
564565
* To be called in process context.
565566
* Return value: 0 on success, non-zero otherwise.

drivers/firewire/ohci.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ struct ar_context {
101101
void *pointer;
102102
unsigned int last_buffer_index;
103103
u32 regs;
104-
struct tasklet_struct tasklet;
104+
struct work_struct work;
105105
};
106106

107107
struct context;
@@ -1016,33 +1016,29 @@ static void ar_recycle_buffers(struct ar_context *ctx, unsigned int end_buffer)
10161016
}
10171017
}
10181018

1019-
static void ar_context_tasklet(unsigned long data)
1019+
static void ohci_ar_context_work(struct work_struct *work)
10201020
{
1021-
struct ar_context *ctx = (struct ar_context *)data;
1021+
struct ar_context *ctx = from_work(ctx, work, work);
10221022
unsigned int end_buffer_index, end_buffer_offset;
10231023
void *p, *end;
10241024

10251025
p = ctx->pointer;
10261026
if (!p)
10271027
return;
10281028

1029-
end_buffer_index = ar_search_last_active_buffer(ctx,
1030-
&end_buffer_offset);
1029+
end_buffer_index = ar_search_last_active_buffer(ctx, &end_buffer_offset);
10311030
ar_sync_buffers_for_cpu(ctx, end_buffer_index, end_buffer_offset);
10321031
end = ctx->buffer + end_buffer_index * PAGE_SIZE + end_buffer_offset;
10331032

10341033
if (end_buffer_index < ar_first_buffer_index(ctx)) {
1035-
/*
1036-
* The filled part of the overall buffer wraps around; handle
1037-
* all packets up to the buffer end here. If the last packet
1038-
* wraps around, its tail will be visible after the buffer end
1039-
* because the buffer start pages are mapped there again.
1040-
*/
1034+
// The filled part of the overall buffer wraps around; handle all packets up to the
1035+
// buffer end here. If the last packet wraps around, its tail will be visible after
1036+
// the buffer end because the buffer start pages are mapped there again.
10411037
void *buffer_end = ctx->buffer + AR_BUFFERS * PAGE_SIZE;
10421038
p = handle_ar_packets(ctx, p, buffer_end);
10431039
if (p < buffer_end)
10441040
goto error;
1045-
/* adjust p to point back into the actual buffer */
1041+
// adjust p to point back into the actual buffer
10461042
p -= AR_BUFFERS * PAGE_SIZE;
10471043
}
10481044

@@ -1057,7 +1053,6 @@ static void ar_context_tasklet(unsigned long data)
10571053
ar_recycle_buffers(ctx, end_buffer_index);
10581054

10591055
return;
1060-
10611056
error:
10621057
ctx->pointer = NULL;
10631058
}
@@ -1073,7 +1068,7 @@ static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci,
10731068

10741069
ctx->regs = regs;
10751070
ctx->ohci = ohci;
1076-
tasklet_init(&ctx->tasklet, ar_context_tasklet, (unsigned long)ctx);
1071+
INIT_WORK(&ctx->work, ohci_ar_context_work);
10771072

10781073
for (i = 0; i < AR_BUFFERS; i++) {
10791074
ctx->pages[i] = dma_alloc_pages(dev, PAGE_SIZE, &dma_addr,
@@ -2238,10 +2233,10 @@ static irqreturn_t irq_handler(int irq, void *data)
22382233
}
22392234

22402235
if (event & OHCI1394_RQPkt)
2241-
tasklet_schedule(&ohci->ar_request_ctx.tasklet);
2236+
queue_work(ohci->card.async_wq, &ohci->ar_request_ctx.work);
22422237

22432238
if (event & OHCI1394_RSPkt)
2244-
tasklet_schedule(&ohci->ar_response_ctx.tasklet);
2239+
queue_work(ohci->card.async_wq, &ohci->ar_response_ctx.work);
22452240

22462241
if (event & OHCI1394_reqTxComplete)
22472242
tasklet_schedule(&ohci->at_request_ctx.tasklet);

0 commit comments

Comments
 (0)