From 9bf71acd65bf190a0ef1bc885a0a664f91beff03 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sat, 17 Jan 2026 23:28:20 +0900 Subject: firewire: core: provide isoc header buffer size outside card driver For single-channel isochronous contexts, the header storage size is hard-coded to PAGE_SIZE. which is inconvenient for protocol implementations requiring more space. This commit refactors the code to obtain the header storage size outside the 1394 OHCI driver. Link: https://lore.kernel.org/r/20260117142823.440811-8-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-card.c | 4 ++-- drivers/firewire/core-iso.c | 8 +++++--- drivers/firewire/core.h | 6 +++--- drivers/firewire/ohci.c | 10 +++++----- include/linux/firewire.h | 7 +++++-- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 0462d7b9e547..a754c6366b97 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -704,8 +704,8 @@ static int dummy_enable_phys_dma(struct fw_card *card, return -ENODEV; } -static struct fw_iso_context *dummy_allocate_iso_context(struct fw_card *card, - int type, int channel, size_t header_size) +static struct fw_iso_context *dummy_allocate_iso_context(struct fw_card *card, int type, + int channel, size_t header_size, size_t header_storage_size) { return ERR_PTR(-ENODEV); } diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index fbbd14d21ca4..3190b2ca1298 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -138,12 +138,13 @@ size_t fw_iso_buffer_lookup(struct fw_iso_buffer *buffer, dma_addr_t completed) } struct fw_iso_context *__fw_iso_context_create(struct fw_card *card, int type, int channel, - int speed, size_t header_size, union fw_iso_callback callback, void *callback_data) + int speed, size_t header_size, size_t header_storage_size, + union fw_iso_callback callback, void *callback_data) { struct fw_iso_context *ctx; - ctx = card->driver->allocate_iso_context(card, - type, channel, header_size); + ctx = card->driver->allocate_iso_context(card, type, channel, header_size, + header_storage_size); if (IS_ERR(ctx)) return ctx; @@ -153,6 +154,7 @@ struct fw_iso_context *__fw_iso_context_create(struct fw_card *card, int type, i ctx->speed = speed; ctx->flags = 0; ctx->header_size = header_size; + ctx->header_storage_size = header_storage_size; ctx->callback = callback; ctx->callback_data = callback_data; diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index e0ae948605e1..8b49d7480c37 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -100,8 +100,8 @@ struct fw_card_driver { void (*write_csr)(struct fw_card *card, int csr_offset, u32 value); struct fw_iso_context * - (*allocate_iso_context)(struct fw_card *card, - int type, int channel, size_t header_size); + (*allocate_iso_context)(struct fw_card *card, int type, int channel, size_t header_size, + size_t header_storage_size); void (*free_iso_context)(struct fw_iso_context *ctx); int (*start_iso)(struct fw_iso_context *ctx, @@ -178,7 +178,7 @@ static inline struct fw_iso_context *fw_iso_mc_context_create(struct fw_card *ca { union fw_iso_callback cb = { .mc = callback }; - return __fw_iso_context_create(card, FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL, 0, 0, 0, cb, + return __fw_iso_context_create(card, FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL, 0, 0, 0, 0, cb, callback_data); } diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 888c43940999..1c868c1e4a49 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -2755,7 +2755,7 @@ static void copy_iso_headers(struct iso_context *ctx, const u32 *dma_hdr) { u32 *ctx_hdr; - if (ctx->sc.header_length + ctx->base.header_size > PAGE_SIZE) { + if (ctx->sc.header_length + ctx->base.header_size > ctx->base.header_storage_size) { if (ctx->base.flags & FW_ISO_CONTEXT_FLAG_DROP_OVERFLOW_HEADERS) return; flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_HEADER_OVERFLOW); @@ -2924,7 +2924,7 @@ static int handle_it_packet(struct context *context, sync_it_packet_for_cpu(context, d); - if (ctx->sc.header_length + 4 > PAGE_SIZE) { + if (ctx->sc.header_length + 4 > ctx->base.header_storage_size) { if (ctx->base.flags & FW_ISO_CONTEXT_FLAG_DROP_OVERFLOW_HEADERS) return 1; flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_HEADER_OVERFLOW); @@ -2954,8 +2954,8 @@ static void set_multichannel_mask(struct fw_ohci *ohci, u64 channels) ohci->mc_channels = channels; } -static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, - int type, int channel, size_t header_size) +static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, int type, int channel, + size_t header_size, size_t header_storage_size) { struct fw_ohci *ohci = fw_ohci(card); void *header __free(kvfree) = NULL; @@ -3016,7 +3016,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, if (type != FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) { ctx->sc.header_length = 0; - header = kvmalloc(PAGE_SIZE, GFP_KERNEL); + header = kvmalloc(header_storage_size, GFP_KERNEL); if (!header) { ret = -ENOMEM; goto out; diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 71d5cc8f28ce..8bf568471588 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -558,12 +558,14 @@ struct fw_iso_context { int speed; int flags; size_t header_size; + size_t header_storage_size; union fw_iso_callback callback; void *callback_data; }; struct fw_iso_context *__fw_iso_context_create(struct fw_card *card, int type, int channel, - int speed, size_t header_size, union fw_iso_callback callback, void *callback_data); + int speed, size_t header_size, size_t header_storage_size, + union fw_iso_callback callback, void *callback_data); int fw_iso_context_set_channels(struct fw_iso_context *ctx, u64 *channels); int fw_iso_context_queue(struct fw_iso_context *ctx, struct fw_iso_packet *packet, @@ -578,7 +580,8 @@ static inline struct fw_iso_context *fw_iso_context_create(struct fw_card *card, { union fw_iso_callback cb = { .sc = callback }; - return __fw_iso_context_create(card, type, channel, speed, header_size, cb, callback_data); + return __fw_iso_context_create(card, type, channel, speed, header_size, PAGE_SIZE, cb, + callback_data); } /** -- cgit v1.2.3