]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
firewire: core: provide isoc header buffer size outside card driver
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sat, 17 Jan 2026 14:28:20 +0000 (23:28 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 18 Jan 2026 08:18:48 +0000 (17:18 +0900)
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 <o-takashi@sakamocchi.jp>
drivers/firewire/core-card.c
drivers/firewire/core-iso.c
drivers/firewire/core.h
drivers/firewire/ohci.c
include/linux/firewire.h

index 0462d7b9e547a9655a47c90a102b40b04cb4842b..a754c6366b97e0d8e65c973539e64ab9cb8b9fd8 100644 (file)
@@ -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);
 }
index fbbd14d21ca41cf7b70c8ade0a521ce82902affb..3190b2ca129817cac7d17085b43dcb87200774d4 100644 (file)
@@ -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;
 
index e0ae948605e16d8159e6ae421e86a85813378642..8b49d7480c37574df5e84f0609b514362d0417ef 100644 (file)
@@ -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);
 }
 
index 888c43940999a356c78fb313b0a10a9f1b751958..1c868c1e4a490fb977b30fbbbb6d97ae870a9029 100644 (file)
@@ -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;
index 71d5cc8f28cefedbe33cf04d670b000991eed790..8bf56847158834050eaa42b990979c2dda3657be 100644 (file)
@@ -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);
 }
 
 /**