public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size
@ 2026-01-17 14:28 Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 1/9] firewire: core: add function variants for isochronous context creation Takashi Sakamoto
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-17 14:28 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

Hi,

Currently ALSA IEC 61883-1/6 packet streaming engine provides the maximum
PCM buffer size constraints to drivers for audio and music units in
IEEE 1394 bus, due to hard-coded size of isochronous context header for
1394 OHCI IR context.

The limitation is inconvenient a bit, and this patchset removes it by
allowing the drivers to configure the size of isochronous context
header.

To sound subsystem maintainer, I'd like to send the last patch to
mainline in my side.

Takashi Sakamoto (9):
  firewire: core: add function variants for isochronous context creation
  firewire: ohci: refactor isoc single-channel state using a union
  firewire: ohci: code refactoring to use union for isoc multiple
    channel state
  firewire: ohci: use cleanup helper for isoc context header allocation
  firewire: core: add flags member for isochronous context structure
  firewire: ohci: allocate isoc context header by kvmalloc()
  firewire: core: provide isoc header buffer size outside card driver
  firewire: core: add fw_iso_context_create() variant with header
    storage size
  ALSA: firewire: remove PCM buffer size constraint from isoc context
    header

 drivers/firewire/core-card.c  |   4 +-
 drivers/firewire/core-cdev.c  |  30 ++--------
 drivers/firewire/core-iso.c   |  16 ++---
 drivers/firewire/core.h       |  13 +++-
 drivers/firewire/ohci.c       | 110 +++++++++++++++++++---------------
 include/linux/firewire.h      |  33 ++++++++--
 sound/firewire/amdtp-stream.c |  31 +++-------
 7 files changed, 125 insertions(+), 112 deletions(-)


base-commit: a4cd9860fa085f0d04d2065f4c151fcde9fcdf4a
-- 
2.51.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/9] firewire: core: add function variants for isochronous context creation
  2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
@ 2026-01-17 14:28 ` Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 2/9] firewire: ohci: refactor isoc single-channel state using a union Takashi Sakamoto
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-17 14:28 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

The fw_iso_callback union was added by a commit ebe4560ed5c ("firewire:
Remove function callback casts") to remove function pointer cast.

That change affected the cdev layer of the core code, but it is more
convenient for fw_iso_context_create() to accept the union directly.

This commit renames and changes the existing function to take the union
argument, and add static inline wrapper functions as variants.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/core-cdev.c | 28 +++-------------------------
 drivers/firewire/core-iso.c  |  9 ++++-----
 drivers/firewire/core.h      |  9 +++++++++
 include/linux/firewire.h     | 14 +++++++++++---
 4 files changed, 27 insertions(+), 33 deletions(-)

diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index bb4d0f938f5b..c26bea253208 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -1026,25 +1026,10 @@ static enum dma_data_direction iso_dma_direction(struct fw_iso_context *context)
 			return DMA_FROM_DEVICE;
 }
 
-static struct fw_iso_context *fw_iso_mc_context_create(struct fw_card *card,
-						fw_iso_mc_callback_t callback,
-						void *callback_data)
-{
-	struct fw_iso_context *ctx;
-
-	ctx = fw_iso_context_create(card, FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL,
-				    0, 0, 0, NULL, callback_data);
-	if (!IS_ERR(ctx))
-		ctx->callback.mc = callback;
-
-	return ctx;
-}
-
 static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
 {
 	struct fw_cdev_create_iso_context *a = &arg->create_iso_context;
 	struct fw_iso_context *context;
-	union fw_iso_callback cb;
 	int ret;
 
 	BUILD_BUG_ON(FW_CDEV_ISO_CONTEXT_TRANSMIT != FW_ISO_CONTEXT_TRANSMIT ||
@@ -1056,20 +1041,15 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
 	case FW_ISO_CONTEXT_TRANSMIT:
 		if (a->speed > SCODE_3200 || a->channel > 63)
 			return -EINVAL;
-
-		cb.sc = iso_callback;
 		break;
 
 	case FW_ISO_CONTEXT_RECEIVE:
 		if (a->header_size < 4 || (a->header_size & 3) ||
 		    a->channel > 63)
 			return -EINVAL;
-
-		cb.sc = iso_callback;
 		break;
 
 	case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL:
-		cb.mc = iso_mc_callback;
 		break;
 
 	default:
@@ -1077,12 +1057,10 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
 	}
 
 	if (a->type == FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL)
-		context = fw_iso_mc_context_create(client->device->card, cb.mc,
-						   client);
+		context = fw_iso_mc_context_create(client->device->card, iso_mc_callback, client);
 	else
-		context = fw_iso_context_create(client->device->card, a->type,
-						a->channel, a->speed,
-						a->header_size, cb.sc, client);
+		context = fw_iso_context_create(client->device->card, a->type, a->channel, a->speed,
+						a->header_size, iso_callback, client);
 	if (IS_ERR(context))
 		return PTR_ERR(context);
 	if (client->version < FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW)
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c
index 3f36243ec0c1..d9b8896c8ce1 100644
--- a/drivers/firewire/core-iso.c
+++ b/drivers/firewire/core-iso.c
@@ -137,9 +137,8 @@ size_t fw_iso_buffer_lookup(struct fw_iso_buffer *buffer, dma_addr_t completed)
 	return 0;
 }
 
-struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
-		int type, int channel, int speed, size_t header_size,
-		fw_iso_callback_t 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)
 {
 	struct fw_iso_context *ctx;
 
@@ -153,7 +152,7 @@ struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
 	ctx->channel = channel;
 	ctx->speed = speed;
 	ctx->header_size = header_size;
-	ctx->callback.sc = callback;
+	ctx->callback = callback;
 	ctx->callback_data = callback_data;
 
 	trace_isoc_outbound_allocate(ctx, channel, speed);
@@ -162,7 +161,7 @@ struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
 
 	return ctx;
 }
-EXPORT_SYMBOL(fw_iso_context_create);
+EXPORT_SYMBOL(__fw_iso_context_create);
 
 void fw_iso_context_destroy(struct fw_iso_context *ctx)
 {
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index 26868f007131..e0ae948605e1 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -173,6 +173,15 @@ static inline void fw_iso_context_init_work(struct fw_iso_context *ctx, work_fun
 	INIT_WORK(&ctx->work, func);
 }
 
+static inline struct fw_iso_context *fw_iso_mc_context_create(struct fw_card *card,
+		fw_iso_mc_callback_t callback, void *callback_data)
+{
+	union fw_iso_callback cb = { .mc = callback };
+
+	return __fw_iso_context_create(card, FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL, 0, 0, 0, cb,
+				       callback_data);
+}
+
 
 /* -topology */
 
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 09c8484f7430..68161b8a8a58 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -558,9 +558,8 @@ struct fw_iso_context {
 	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,
-		fw_iso_callback_t 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 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,
@@ -569,6 +568,15 @@ int fw_iso_context_queue(struct fw_iso_context *ctx,
 void fw_iso_context_queue_flush(struct fw_iso_context *ctx);
 int fw_iso_context_flush_completions(struct fw_iso_context *ctx);
 
+static inline struct fw_iso_context *fw_iso_context_create(struct fw_card *card, int type,
+		int channel, int speed, size_t header_size, fw_iso_callback_t callback,
+		void *callback_data)
+{
+	union fw_iso_callback cb = { .sc = callback };
+
+	return __fw_iso_context_create(card, type, channel, speed, header_size, cb, callback_data);
+}
+
 /**
  * fw_iso_context_schedule_flush_completions() - schedule work item to process isochronous context.
  * @ctx: the isochronous context
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/9] firewire: ohci: refactor isoc single-channel state using a union
  2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 1/9] firewire: core: add function variants for isochronous context creation Takashi Sakamoto
@ 2026-01-17 14:28 ` Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 3/9] firewire: ohci: code refactoring to use union for isoc multiple channel state Takashi Sakamoto
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-17 14:28 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

In 1394 OHCI driver, some members of struct iso_context are only used for
single-channel isochronous contexts.

This commit groups these members into a union.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/ohci.c | 68 +++++++++++++++++++++++++----------------
 1 file changed, 41 insertions(+), 27 deletions(-)

diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 339047a2e768..b1dc0c4feb86 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -168,14 +168,18 @@ struct at_context {
 struct iso_context {
 	struct fw_iso_context base;
 	struct context context;
-	void *header;
-	size_t header_length;
 	unsigned long flushing_completions;
 	u32 mc_buffer_bus;
 	u16 mc_completed;
-	u16 last_timestamp;
 	u8 sync;
 	u8 tags;
+	union {
+		struct {
+			u16 last_timestamp;
+			size_t header_length;
+			void *header;
+		} sc;
+	};
 };
 
 #define CONFIG_ROM_SIZE		(CSR_CONFIG_ROM_END - CSR_CONFIG_ROM)
@@ -2735,29 +2739,28 @@ static void ohci_write_csr(struct fw_card *card, int csr_offset, u32 value)
 
 static void flush_iso_completions(struct iso_context *ctx, enum fw_iso_context_completions_cause cause)
 {
-	trace_isoc_inbound_single_completions(&ctx->base, ctx->last_timestamp, cause, ctx->header,
-					      ctx->header_length);
-	trace_isoc_outbound_completions(&ctx->base, ctx->last_timestamp, cause, ctx->header,
-					ctx->header_length);
+	trace_isoc_inbound_single_completions(&ctx->base, ctx->sc.last_timestamp, cause,
+					      ctx->sc.header, ctx->sc.header_length);
+	trace_isoc_outbound_completions(&ctx->base, ctx->sc.last_timestamp, cause, ctx->sc.header,
+					ctx->sc.header_length);
 
-	ctx->base.callback.sc(&ctx->base, ctx->last_timestamp,
-			      ctx->header_length, ctx->header,
-			      ctx->base.callback_data);
-	ctx->header_length = 0;
+	ctx->base.callback.sc(&ctx->base, ctx->sc.last_timestamp, ctx->sc.header_length,
+			      ctx->sc.header, ctx->base.callback_data);
+	ctx->sc.header_length = 0;
 }
 
 static void copy_iso_headers(struct iso_context *ctx, const u32 *dma_hdr)
 {
 	u32 *ctx_hdr;
 
-	if (ctx->header_length + ctx->base.header_size > PAGE_SIZE) {
+	if (ctx->sc.header_length + ctx->base.header_size > PAGE_SIZE) {
 		if (ctx->base.drop_overflow_headers)
 			return;
 		flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_HEADER_OVERFLOW);
 	}
 
-	ctx_hdr = ctx->header + ctx->header_length;
-	ctx->last_timestamp = (u16)le32_to_cpu((__force __le32)dma_hdr[0]);
+	ctx_hdr = ctx->sc.header + ctx->sc.header_length;
+	ctx->sc.last_timestamp = (u16)le32_to_cpu((__force __le32)dma_hdr[0]);
 
 	/*
 	 * The two iso header quadlets are byteswapped to little
@@ -2770,7 +2773,7 @@ static void copy_iso_headers(struct iso_context *ctx, const u32 *dma_hdr)
 		ctx_hdr[1] = swab32(dma_hdr[0]); /* timestamp */
 	if (ctx->base.header_size > 8)
 		memcpy(&ctx_hdr[2], &dma_hdr[2], ctx->base.header_size - 8);
-	ctx->header_length += ctx->base.header_size;
+	ctx->sc.header_length += ctx->base.header_size;
 }
 
 static int handle_ir_packet_per_buffer(struct context *context,
@@ -2920,18 +2923,18 @@ static int handle_it_packet(struct context *context,
 
 	sync_it_packet_for_cpu(context, d);
 
-	if (ctx->header_length + 4 > PAGE_SIZE) {
+	if (ctx->sc.header_length + 4 > PAGE_SIZE) {
 		if (ctx->base.drop_overflow_headers)
 			return 1;
 		flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_HEADER_OVERFLOW);
 	}
 
-	ctx_hdr = ctx->header + ctx->header_length;
-	ctx->last_timestamp = le16_to_cpu(last->res_count);
+	ctx_hdr = ctx->sc.header + ctx->sc.header_length;
+	ctx->sc.last_timestamp = le16_to_cpu(last->res_count);
 	/* Present this value as big-endian to match the receive code */
 	*ctx_hdr = cpu_to_be32((le16_to_cpu(pd->transfer_status) << 16) |
 			       le16_to_cpu(pd->res_count));
-	ctx->header_length += 4;
+	ctx->sc.header_length += 4;
 
 	if (last->control & cpu_to_le16(DESCRIPTOR_IRQ_ALWAYS))
 		flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_INTERRUPT);
@@ -3008,12 +3011,16 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
 	}
 
 	memset(ctx, 0, sizeof(*ctx));
-	ctx->header_length = 0;
-	ctx->header = (void *) __get_free_page(GFP_KERNEL);
-	if (ctx->header == NULL) {
-		ret = -ENOMEM;
-		goto out;
+
+	if (type != FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) {
+		ctx->sc.header_length = 0;
+		ctx->sc.header = (void *) __get_free_page(GFP_KERNEL);
+		if (!ctx->sc.header) {
+			ret = -ENOMEM;
+			goto out;
+		}
 	}
+
 	ret = context_init(&ctx->context, ohci, regs, callback);
 	if (ret < 0)
 		goto out_with_header;
@@ -3027,7 +3034,10 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
 	return &ctx->base;
 
  out_with_header:
-	free_page((unsigned long)ctx->header);
+	if (type != FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) {
+		free_page((unsigned long)ctx->sc.header);
+		ctx->sc.header = NULL;
+	}
  out:
 	scoped_guard(spinlock_irq, &ohci->lock) {
 		switch (type) {
@@ -3127,7 +3137,11 @@ static void ohci_free_iso_context(struct fw_iso_context *base)
 
 	ohci_stop_iso(base);
 	context_release(&ctx->context);
-	free_page((unsigned long)ctx->header);
+
+	if (base->type != FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) {
+		free_page((unsigned long)ctx->sc.header);
+		ctx->sc.header = NULL;
+	}
 
 	guard(spinlock_irqsave)(&ohci->lock);
 
@@ -3475,7 +3489,7 @@ static int ohci_flush_iso_completions(struct fw_iso_context *base)
 		switch (base->type) {
 		case FW_ISO_CONTEXT_TRANSMIT:
 		case FW_ISO_CONTEXT_RECEIVE:
-			if (ctx->header_length != 0)
+			if (ctx->sc.header_length != 0)
 				flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_FLUSH);
 			break;
 		case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL:
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/9] firewire: ohci: code refactoring to use union for isoc multiple channel state
  2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 1/9] firewire: core: add function variants for isochronous context creation Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 2/9] firewire: ohci: refactor isoc single-channel state using a union Takashi Sakamoto
@ 2026-01-17 14:28 ` Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 4/9] firewire: ohci: use cleanup helper for isoc context header allocation Takashi Sakamoto
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-17 14:28 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

In 1394 OHCI driver, some members of struct iso_context are only used for
multi-channel isochronous contexts.

This commit uses a union for these members to clearly separate
multi-channel specific state.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/ohci.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index b1dc0c4feb86..5d9857cbbd24 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -169,8 +169,6 @@ struct iso_context {
 	struct fw_iso_context base;
 	struct context context;
 	unsigned long flushing_completions;
-	u32 mc_buffer_bus;
-	u16 mc_completed;
 	u8 sync;
 	u8 tags;
 	union {
@@ -179,6 +177,10 @@ struct iso_context {
 			size_t header_length;
 			void *header;
 		} sc;
+		struct {
+			u32 buffer_bus;
+			u16 completed;
+		} mc;
 	};
 };
 
@@ -2826,8 +2828,8 @@ static int handle_ir_buffer_fill(struct context *context,
 	buffer_dma = le32_to_cpu(last->data_address);
 
 	if (completed > 0) {
-		ctx->mc_buffer_bus = buffer_dma;
-		ctx->mc_completed = completed;
+		ctx->mc.buffer_bus = buffer_dma;
+		ctx->mc.completed = completed;
 	}
 
 	if (res_count != 0)
@@ -2846,7 +2848,7 @@ static int handle_ir_buffer_fill(struct context *context,
 		ctx->base.callback.mc(&ctx->base,
 				      buffer_dma + completed,
 				      ctx->base.callback_data);
-		ctx->mc_completed = 0;
+		ctx->mc.completed = 0;
 	}
 
 	return 1;
@@ -2855,17 +2857,16 @@ static int handle_ir_buffer_fill(struct context *context,
 static void flush_ir_buffer_fill(struct iso_context *ctx)
 {
 	dma_sync_single_range_for_cpu(ctx->context.ohci->card.device,
-				      ctx->mc_buffer_bus & PAGE_MASK,
-				      ctx->mc_buffer_bus & ~PAGE_MASK,
-				      ctx->mc_completed, DMA_FROM_DEVICE);
+				      ctx->mc.buffer_bus & PAGE_MASK,
+				      ctx->mc.buffer_bus & ~PAGE_MASK,
+				      ctx->mc.completed, DMA_FROM_DEVICE);
 
-	trace_isoc_inbound_multiple_completions(&ctx->base, ctx->mc_completed,
+	trace_isoc_inbound_multiple_completions(&ctx->base, ctx->mc.completed,
 						FW_ISO_CONTEXT_COMPLETIONS_CAUSE_FLUSH);
 
-	ctx->base.callback.mc(&ctx->base,
-			      ctx->mc_buffer_bus + ctx->mc_completed,
+	ctx->base.callback.mc(&ctx->base, ctx->mc.buffer_bus + ctx->mc.completed,
 			      ctx->base.callback_data);
-	ctx->mc_completed = 0;
+	ctx->mc.completed = 0;
 }
 
 static inline void sync_it_packet_for_cpu(struct context *context,
@@ -3028,7 +3029,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
 
 	if (type == FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) {
 		set_multichannel_mask(ohci, 0);
-		ctx->mc_completed = 0;
+		ctx->mc.completed = 0;
 	}
 
 	return &ctx->base;
@@ -3493,7 +3494,7 @@ static int ohci_flush_iso_completions(struct fw_iso_context *base)
 				flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_FLUSH);
 			break;
 		case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL:
-			if (ctx->mc_completed != 0)
+			if (ctx->mc.completed != 0)
 				flush_ir_buffer_fill(ctx);
 			break;
 		default:
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/9] firewire: ohci: use cleanup helper for isoc context header allocation
  2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
                   ` (2 preceding siblings ...)
  2026-01-17 14:28 ` [PATCH 3/9] firewire: ohci: code refactoring to use union for isoc multiple channel state Takashi Sakamoto
@ 2026-01-17 14:28 ` Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 5/9] firewire: core: add flags member for isochronous context structure Takashi Sakamoto
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-17 14:28 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

Some cleanup helpers are useful in error path after memory allocation for
header storage.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/ohci.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 5d9857cbbd24..6760c8d12637 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -2958,6 +2958,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
 				int type, int channel, size_t header_size)
 {
 	struct fw_ohci *ohci = fw_ohci(card);
+	void *header __free(free_page) = NULL;
 	struct iso_context *ctx;
 	descriptor_callback_t callback;
 	u64 *channels;
@@ -3015,8 +3016,8 @@ 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;
-		ctx->sc.header = (void *) __get_free_page(GFP_KERNEL);
-		if (!ctx->sc.header) {
+		header = (void *) __get_free_page(GFP_KERNEL);
+		if (!header) {
 			ret = -ENOMEM;
 			goto out;
 		}
@@ -3024,21 +3025,17 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
 
 	ret = context_init(&ctx->context, ohci, regs, callback);
 	if (ret < 0)
-		goto out_with_header;
+		goto out;
 	fw_iso_context_init_work(&ctx->base, ohci_isoc_context_work);
 
-	if (type == FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) {
+	if (type != FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) {
+		ctx->sc.header = no_free_ptr(header);
+	} else {
 		set_multichannel_mask(ohci, 0);
 		ctx->mc.completed = 0;
 	}
 
 	return &ctx->base;
-
- out_with_header:
-	if (type != FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) {
-		free_page((unsigned long)ctx->sc.header);
-		ctx->sc.header = NULL;
-	}
  out:
 	scoped_guard(spinlock_irq, &ohci->lock) {
 		switch (type) {
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/9] firewire: core: add flags member for isochronous context structure
  2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
                   ` (3 preceding siblings ...)
  2026-01-17 14:28 ` [PATCH 4/9] firewire: ohci: use cleanup helper for isoc context header allocation Takashi Sakamoto
@ 2026-01-17 14:28 ` Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 6/9] firewire: ohci: allocate isoc context header by kvmalloc() Takashi Sakamoto
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-17 14:28 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

This is minor code refactoring to add a flag member to the isochronous
context structure. At present, it is used only for the option to drop
packets when the context header overflows.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/core-cdev.c | 2 +-
 drivers/firewire/core-iso.c  | 1 +
 drivers/firewire/ohci.c      | 4 ++--
 include/linux/firewire.h     | 6 +++++-
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index c26bea253208..9e964fdd175c 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -1064,7 +1064,7 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
 	if (IS_ERR(context))
 		return PTR_ERR(context);
 	if (client->version < FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW)
-		context->drop_overflow_headers = true;
+		context->flags |= FW_ISO_CONTEXT_FLAG_DROP_OVERFLOW_HEADERS;
 
 	// We only support one context at this time.
 	scoped_guard(mutex, &client->iso_context_mutex) {
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c
index d9b8896c8ce1..fbbd14d21ca4 100644
--- a/drivers/firewire/core-iso.c
+++ b/drivers/firewire/core-iso.c
@@ -151,6 +151,7 @@ struct fw_iso_context *__fw_iso_context_create(struct fw_card *card, int type, i
 	ctx->type = type;
 	ctx->channel = channel;
 	ctx->speed = speed;
+	ctx->flags = 0;
 	ctx->header_size = header_size;
 	ctx->callback = callback;
 	ctx->callback_data = callback_data;
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 6760c8d12637..8bba70b65ad7 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -2756,7 +2756,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->base.drop_overflow_headers)
+		if (ctx->base.flags & FW_ISO_CONTEXT_FLAG_DROP_OVERFLOW_HEADERS)
 			return;
 		flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_HEADER_OVERFLOW);
 	}
@@ -2925,7 +2925,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->base.drop_overflow_headers)
+		if (ctx->base.flags & FW_ISO_CONTEXT_FLAG_DROP_OVERFLOW_HEADERS)
 			return 1;
 		flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_HEADER_OVERFLOW);
 	}
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 68161b8a8a58..71d5cc8f28ce 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -546,13 +546,17 @@ union fw_iso_callback {
 	fw_iso_mc_callback_t mc;
 };
 
+enum fw_iso_context_flag {
+	FW_ISO_CONTEXT_FLAG_DROP_OVERFLOW_HEADERS = BIT(0),
+};
+
 struct fw_iso_context {
 	struct fw_card *card;
 	struct work_struct work;
 	int type;
 	int channel;
 	int speed;
-	bool drop_overflow_headers;
+	int flags;
 	size_t header_size;
 	union fw_iso_callback callback;
 	void *callback_data;
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/9] firewire: ohci: allocate isoc context header by kvmalloc()
  2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
                   ` (4 preceding siblings ...)
  2026-01-17 14:28 ` [PATCH 5/9] firewire: core: add flags member for isochronous context structure Takashi Sakamoto
@ 2026-01-17 14:28 ` Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 7/9] firewire: core: provide isoc header buffer size outside card driver Takashi Sakamoto
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-17 14:28 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

Isochronous packet handling now runs in a workqueue context, where page
faults is acceptable.

This commit replaces __get_free_page() with kvmalloc() when allocating the
isochronous context header buffer.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/ohci.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 8bba70b65ad7..888c43940999 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -2958,7 +2958,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
 				int type, int channel, size_t header_size)
 {
 	struct fw_ohci *ohci = fw_ohci(card);
-	void *header __free(free_page) = NULL;
+	void *header __free(kvfree) = NULL;
 	struct iso_context *ctx;
 	descriptor_callback_t callback;
 	u64 *channels;
@@ -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 = (void *) __get_free_page(GFP_KERNEL);
+		header = kvmalloc(PAGE_SIZE, GFP_KERNEL);
 		if (!header) {
 			ret = -ENOMEM;
 			goto out;
@@ -3137,7 +3137,7 @@ static void ohci_free_iso_context(struct fw_iso_context *base)
 	context_release(&ctx->context);
 
 	if (base->type != FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) {
-		free_page((unsigned long)ctx->sc.header);
+		kvfree(ctx->sc.header);
 		ctx->sc.header = NULL;
 	}
 
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/9] firewire: core: provide isoc header buffer size outside card driver
  2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
                   ` (5 preceding siblings ...)
  2026-01-17 14:28 ` [PATCH 6/9] firewire: ohci: allocate isoc context header by kvmalloc() Takashi Sakamoto
@ 2026-01-17 14:28 ` Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 8/9] firewire: core: add fw_iso_context_create() variant with header storage size Takashi Sakamoto
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-17 14:28 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

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.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 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);
 }
 
 /**
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/9] firewire: core: add fw_iso_context_create() variant with header storage size
  2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
                   ` (6 preceding siblings ...)
  2026-01-17 14:28 ` [PATCH 7/9] firewire: core: provide isoc header buffer size outside card driver Takashi Sakamoto
@ 2026-01-17 14:28 ` Takashi Sakamoto
  2026-01-17 14:28 ` [PATCH 9/9] ALSA: firewire: remove PCM buffer size constraint from isoc context header Takashi Sakamoto
  2026-01-19  8:52 ` [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
  9 siblings, 0 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-17 14:28 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

This commit adds a new variant of fw_iso_context_create() that allows
specifying the size of the isochronous context header storage at
allocation time.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 include/linux/firewire.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 8bf568471588..986d712e4d94 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -584,6 +584,16 @@ static inline struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
 				       callback_data);
 }
 
+static inline struct fw_iso_context *fw_iso_context_create_with_header_storage_size(
+		struct fw_card *card, int type, int channel, int speed, size_t header_size,
+		size_t header_storage_size, fw_iso_callback_t callback, void *callback_data)
+{
+	union fw_iso_callback cb = { .sc = callback };
+
+	return __fw_iso_context_create(card, type, channel, speed, header_size, header_storage_size,
+				       cb, callback_data);
+}
+
 /**
  * fw_iso_context_schedule_flush_completions() - schedule work item to process isochronous context.
  * @ctx: the isochronous context
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 9/9] ALSA: firewire: remove PCM buffer size constraint from isoc context header
  2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
                   ` (7 preceding siblings ...)
  2026-01-17 14:28 ` [PATCH 8/9] firewire: core: add fw_iso_context_create() variant with header storage size Takashi Sakamoto
@ 2026-01-17 14:28 ` Takashi Sakamoto
  2026-01-19  8:52 ` [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
  9 siblings, 0 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-17 14:28 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

In the IEC 61883-1/6 packet streaming engine, the isochronous context
header stores CIP headers. Previously, the header storage was limited to
PAGE_SIZE, which constrained the maximum PCM buffer size.

There is a function with configurable header size. Now the limitation is
removed.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/amdtp-stream.c | 31 +++++++++----------------------
 1 file changed, 9 insertions(+), 22 deletions(-)

diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index 5cdc34877fc1..223c880af802 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -191,8 +191,6 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
 					struct snd_pcm_runtime *runtime)
 {
 	struct snd_pcm_hardware *hw = &runtime->hw;
-	unsigned int ctx_header_size;
-	unsigned int maximum_usec_per_period;
 	int err;
 
 	hw->info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -212,21 +210,6 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
 	hw->period_bytes_max = hw->period_bytes_min * 2048;
 	hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min;
 
-	// Linux driver for 1394 OHCI controller voluntarily flushes isoc
-	// context when total size of accumulated context header reaches
-	// PAGE_SIZE. This kicks work for the isoc context and brings
-	// callback in the middle of scheduled interrupts.
-	// Although AMDTP streams in the same domain use the same events per
-	// IRQ, use the largest size of context header between IT/IR contexts.
-	// Here, use the value of context header in IR context is for both
-	// contexts.
-	if (!(s->flags & CIP_NO_HEADER))
-		ctx_header_size = IR_CTX_HEADER_SIZE_CIP;
-	else
-		ctx_header_size = IR_CTX_HEADER_SIZE_NO_CIP;
-	maximum_usec_per_period = USEC_PER_SEC * PAGE_SIZE /
-				  CYCLES_PER_SECOND / ctx_header_size;
-
 	// In IEC 61883-6, one isoc packet can transfer events up to the value
 	// of syt interval. This comes from the interval of isoc cycle. As 1394
 	// OHCI controller can generate hardware IRQ per isoc packet, the
@@ -239,9 +222,10 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
 	// Due to the above protocol design, the minimum PCM frames per
 	// interrupt should be double of the value of syt interval, thus it is
 	// 250 usec.
+	// There is no reason, but up to 250 msec to avoid consuming resources so much.
 	err = snd_pcm_hw_constraint_minmax(runtime,
 					   SNDRV_PCM_HW_PARAM_PERIOD_TIME,
-					   250, maximum_usec_per_period);
+					   250, USEC_PER_SEC / 4);
 	if (err < 0)
 		goto end;
 
@@ -261,6 +245,7 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
 				  SNDRV_PCM_HW_PARAM_RATE, -1);
 	if (err < 0)
 		goto end;
+
 	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
 				  apply_constraint_to_size, NULL,
 				  SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
@@ -1715,7 +1700,9 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
 	} else {
 		dir = DMA_TO_DEVICE;
 		type = FW_ISO_CONTEXT_TRANSMIT;
-		ctx_header_size = 0;	// No effect for IT context.
+		// Although no effect for IT context, this value is required to compute the size
+		// of header storage correctly.
+		ctx_header_size = sizeof(__be32);
 	}
 	max_ctx_payload_size = amdtp_stream_get_max_ctx_payload_size(s);
 
@@ -1724,9 +1711,9 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
 		return err;
 	s->queue_size = queue_size;
 
-	s->context = fw_iso_context_create(fw_parent_device(s->unit)->card,
-					  type, channel, speed, ctx_header_size,
-					  amdtp_stream_first_callback, s);
+	s->context = fw_iso_context_create_with_header_storage_size(
+			fw_parent_device(s->unit)->card, type, channel, speed, ctx_header_size,
+			ctx_header_size * queue_size, amdtp_stream_first_callback, s);
 	if (IS_ERR(s->context)) {
 		err = PTR_ERR(s->context);
 		if (err == -EBUSY)
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size
  2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
                   ` (8 preceding siblings ...)
  2026-01-17 14:28 ` [PATCH 9/9] ALSA: firewire: remove PCM buffer size constraint from isoc context header Takashi Sakamoto
@ 2026-01-19  8:52 ` Takashi Sakamoto
  9 siblings, 0 replies; 11+ messages in thread
From: Takashi Sakamoto @ 2026-01-19  8:52 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel, linux-sound

Hi,

On Sat, Jan 17, 2026 at 11:28:13PM +0900, Takashi Sakamoto wrote:
> Hi,
> 
> Currently ALSA IEC 61883-1/6 packet streaming engine provides the maximum
> PCM buffer size constraints to drivers for audio and music units in
> IEEE 1394 bus, due to hard-coded size of isochronous context header for
> 1394 OHCI IR context.
> 
> The limitation is inconvenient a bit, and this patchset removes it by
> allowing the drivers to configure the size of isochronous context
> header.
> 
> To sound subsystem maintainer, I'd like to send the last patch to
> mainline in my side.
> 
> Takashi Sakamoto (9):
>   firewire: core: add function variants for isochronous context creation
>   firewire: ohci: refactor isoc single-channel state using a union
>   firewire: ohci: code refactoring to use union for isoc multiple
>     channel state
>   firewire: ohci: use cleanup helper for isoc context header allocation
>   firewire: core: add flags member for isochronous context structure
>   firewire: ohci: allocate isoc context header by kvmalloc()
>   firewire: core: provide isoc header buffer size outside card driver
>   firewire: core: add fw_iso_context_create() variant with header
>     storage size
>   ALSA: firewire: remove PCM buffer size constraint from isoc context
>     header
> 
>  drivers/firewire/core-card.c  |   4 +-
>  drivers/firewire/core-cdev.c  |  30 ++--------
>  drivers/firewire/core-iso.c   |  16 ++---
>  drivers/firewire/core.h       |  13 +++-
>  drivers/firewire/ohci.c       | 110 +++++++++++++++++++---------------
>  include/linux/firewire.h      |  33 ++++++++--
>  sound/firewire/amdtp-stream.c |  31 +++-------
>  7 files changed, 125 insertions(+), 112 deletions(-)

Applied to for-next branch.


Regards

Takashi Sakamoto

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-01-19  8:52 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-17 14:28 [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto
2026-01-17 14:28 ` [PATCH 1/9] firewire: core: add function variants for isochronous context creation Takashi Sakamoto
2026-01-17 14:28 ` [PATCH 2/9] firewire: ohci: refactor isoc single-channel state using a union Takashi Sakamoto
2026-01-17 14:28 ` [PATCH 3/9] firewire: ohci: code refactoring to use union for isoc multiple channel state Takashi Sakamoto
2026-01-17 14:28 ` [PATCH 4/9] firewire: ohci: use cleanup helper for isoc context header allocation Takashi Sakamoto
2026-01-17 14:28 ` [PATCH 5/9] firewire: core: add flags member for isochronous context structure Takashi Sakamoto
2026-01-17 14:28 ` [PATCH 6/9] firewire: ohci: allocate isoc context header by kvmalloc() Takashi Sakamoto
2026-01-17 14:28 ` [PATCH 7/9] firewire: core: provide isoc header buffer size outside card driver Takashi Sakamoto
2026-01-17 14:28 ` [PATCH 8/9] firewire: core: add fw_iso_context_create() variant with header storage size Takashi Sakamoto
2026-01-17 14:28 ` [PATCH 9/9] ALSA: firewire: remove PCM buffer size constraint from isoc context header Takashi Sakamoto
2026-01-19  8:52 ` [PATCH 0/9] firewire: core: add fw_iso_context() variant with configurable isoc header size Takashi Sakamoto

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox