linux1394-devel Mailing List for IEEE 1394 for Linux
Brought to you by:
aeb,
bencollins
You can subscribe to this list here.
| 2000 |
Jan
|
Feb
|
Mar
(39) |
Apr
(154) |
May
(172) |
Jun
(237) |
Jul
(127) |
Aug
(135) |
Sep
(193) |
Oct
(175) |
Nov
(173) |
Dec
(148) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2001 |
Jan
(161) |
Feb
(225) |
Mar
(193) |
Apr
(158) |
May
(179) |
Jun
(292) |
Jul
(146) |
Aug
(134) |
Sep
(185) |
Oct
(190) |
Nov
(149) |
Dec
(161) |
| 2002 |
Jan
(186) |
Feb
(236) |
Mar
(254) |
Apr
(207) |
May
(189) |
Jun
(182) |
Jul
(202) |
Aug
(155) |
Sep
(149) |
Oct
(449) |
Nov
(191) |
Dec
(108) |
| 2003 |
Jan
(174) |
Feb
(242) |
Mar
(243) |
Apr
(255) |
May
(202) |
Jun
(290) |
Jul
(237) |
Aug
(178) |
Sep
(101) |
Oct
(153) |
Nov
(144) |
Dec
(95) |
| 2004 |
Jan
(162) |
Feb
(278) |
Mar
(282) |
Apr
(152) |
May
(127) |
Jun
(138) |
Jul
(94) |
Aug
(63) |
Sep
(64) |
Oct
(150) |
Nov
(102) |
Dec
(197) |
| 2005 |
Jan
(102) |
Feb
(172) |
Mar
(89) |
Apr
(158) |
May
(139) |
Jun
(160) |
Jul
(288) |
Aug
(89) |
Sep
(201) |
Oct
(92) |
Nov
(190) |
Dec
(139) |
| 2006 |
Jan
(121) |
Feb
(204) |
Mar
(133) |
Apr
(134) |
May
(91) |
Jun
(226) |
Jul
(122) |
Aug
(101) |
Sep
(144) |
Oct
(141) |
Nov
|
Dec
|
| 2023 |
Jan
(19) |
Feb
(1) |
Mar
(5) |
Apr
(5) |
May
(33) |
Jun
(17) |
Jul
|
Aug
|
Sep
(3) |
Oct
(1) |
Nov
(5) |
Dec
(40) |
| 2024 |
Jan
(26) |
Feb
(14) |
Mar
(26) |
Apr
(46) |
May
(17) |
Jun
(47) |
Jul
(23) |
Aug
(72) |
Sep
(42) |
Oct
(6) |
Nov
(2) |
Dec
(1) |
| 2025 |
Jan
(2) |
Feb
(1) |
Mar
(4) |
Apr
(2) |
May
|
Jun
(25) |
Jul
(12) |
Aug
(19) |
Sep
(69) |
Oct
(19) |
Nov
(16) |
Dec
(5) |
| 2026 |
Jan
(28) |
Feb
(3) |
Mar
(2) |
Apr
(5) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Takashi S. <o-t...@sa...> - 2026-04-23 14:20:25
|
Hi, It is unclear who is responsible for maintaining the 'ieee1394_device_id' structure in include/linux/mod_devicetable.h, but if it falls under my responsibility (which seems likely), I would prefer to postpone applying these patches, or at least exclude them from this merge window. After reading the discussions around the UAPI, I am not fully convinced that your patches appear to provide clear benefits to existing IEEE 1394 bus users or their software. From my perspective, the motivation appears to be primarily related to the CHERI extension work. As you know, this subsystem is quite marginal in the Linux kernel codebase. Given that, it might be worth considering whether this subsystem should be excluded from the build target when capability pointers are enabled (e.g. via Kconfig, if available), since it does not appear to work outside the ILP32 or LP64 data models. It may be worth carefully considering where effort is best spent. I can understand the merits of CHERI extensions, but changes related to this subsystem would likely be acceptable only after the kernel core functions have been updated. That said, this is just my current view. I would welcome any feedback or objections. Besides, it is still one of my tasks to figure out how to adapt the UAPI structures and the firewire core implementations to non-ILP32/LP64 data models. Thanks Takashi Sakamoto On Sun, Apr 19, 2026 at 08:42:12AM +0200, Uwe Kleine-König (The Capable Hub) wrote: > Hello, > > <linux/mod_devicetable.h> contains several device_id structs for various > device types. > > Most of them have one of: > > - kernel_ulong_t driver_data (sometimes called "driver_info", sometimes > the type is plain unsigned long) > - const void *data (sometimes called "driver_data" or "context", sometimes not const) > > A considerable amount of drivers for the first category uses the > unsigned long variable to store a pointer. This involves casting both > for assignment and usage. > > An additional complication exists for the CHERI hardware extension > where sizeof(void *) > sizeof(unsigned long). So with that an unsigned > long variable cannot be used to store a pointer. > > To address both issues this series replaces the unsigned long variable > by an anonymous union containing both an unsigned long and a pointer. > > For all non-CHERI architectures this isn't an ABI change because all > have sizeof(void *) == sizeof(unsigned long). > > The first patch changes the definition of struct ieee1394_device_id. The > second drops some casts in sound drivers. (There are no other firewire > drivers that could benefit.) I adapted all sound drivers in a single > patch, tell me if I should split per driver. > > For merging I suggest to take the whole series via the ALSA tree in the > next merge window, as there are no modified files that are specific to > firewire only and the second patch depends on the first. > > Best regards > Uwe > > Uwe Kleine-König (The Capable Hub) (2): > firewire: Simplify storing pointers in device id struct > ALSA: firewire: Make use of ieee1394's .driver_data_ptr > > include/linux/mod_devicetable.h | 5 ++++- > sound/firewire/dice/dice.c | 34 ++++++++++++++++----------------- > sound/firewire/fireface/ff.c | 12 ++++++------ > sound/firewire/motu/motu.c | 6 +++--- > sound/firewire/oxfw/oxfw.c | 4 ++-- > 5 files changed, 32 insertions(+), 29 deletions(-) > > > base-commit: 028ef9c96e96197026887c0f092424679298aae8 > -- > 2.47.3 > |
|
From: Takashi S. <o-t...@sa...> - 2026-04-21 12:54:16
|
Hi, On Mon, Apr 20, 2026 at 07:39:32PM +0200, Christian A. Ehrhardt wrote: > > Hi, > > On Mon, Apr 20, 2026 at 06:08:16PM +0900, Takashi Sakamoto wrote: > > Just out of curiosity, what does the CHERI extension adopted to RISC-V > > architecture require in terms of kernel programming? Is taking extra > > care when storing pointer values in long-type variables sufficient in > > driver code? > > That is a significant part but there is more to it (entry code, > register size changes, the UABI should better be CHERI aware, ...). > > But the issue that a pointer does not fit into an unsigned long > is an issue that pops up all over the kernel while most other > changes are more localized. > > There is a working linux kernel in the CHERI alliance github here: > https://github.com/CHERI-Alliance/linux/tree/codasip-cheri-riscv-6.18 > That definitely needs more cleanup but it does work. > Previous work from ARM for the morello project (another CHERI > enabled platform) is available here: > https://git.morello-project.org/morello/kernel/linux > These should give a rough idea of what is required. > > Fixing unsigned long vs. uintptr_t issues helps a lot with this > because it reduces the diff. But it is also a general cleanup. Thsnks for the references. It looks like there is not much to consider outside of mm subsystem. But I have some concerns if supporting ARM/RISC-V adoptation of CHERI extension in Linux FireWire subsystem. Any structures in UAPI header of this subsystem are defined with an assumption that the size of pointer in the existing System V architectures is up to 64 bits at most. We can see many usage of '__u64' type member for pointers (e.g. 'rom' in fw_cdev_get_info structure). I imagine to need defining specific structures for this kind of 'fat' pointer. (The same assumption lays on compat ioctl.) As another concern is that the padding in structure. As long as I know, any 64 bit architecture for System V ABI has 8 bit alignment rule, and any structure in UAPI header of this subsystem are carefully defined not to have different sizes between x86/32bit/64bit architectures, except for 'fw_cdev_event_response' structure (see 'drivers/firewire/uapi-test.c'). As a quick glance, the size of pointer in ARM CHERI extension seems to be 129 bit. In this case, what size of alignment rule is applied? Is there 7 bit padding after pointer member in any aggregates? Thanks Takashi Sakamoto |
|
From: Takashi S. <o-t...@sa...> - 2026-04-20 09:08:30
|
Hi, Thanks for the patches. As far as I can see, they can be applied neither any compilation failures and running regressions. We are in the middle of merge window for v7.2. I had not planned to send any changes to upstream for firewire subsystem, but there is still some time before it closes. If the sound subsystem maintainer does not mind, I would like to proceed. Just out of curiosity, what does the CHERI extension adopted to RISC-V architecture require in terms of kernel programming? Is taking extra care when storing pointer values in long-type variables sufficient in driver code? Thanks Takashi Sakamoto On Sun, Apr 19, 2026 at 08:42:12AM +0200, Uwe Kleine-König (The Capable Hub) wrote: > Hello, > > <linux/mod_devicetable.h> contains several device_id structs for various > device types. > > Most of them have one of: > > - kernel_ulong_t driver_data (sometimes called "driver_info", sometimes > the type is plain unsigned long) > - const void *data (sometimes called "driver_data" or "context", sometimes not const) > > A considerable amount of drivers for the first category uses the > unsigned long variable to store a pointer. This involves casting both > for assignment and usage. > > An additional complication exists for the CHERI hardware extension > where sizeof(void *) > sizeof(unsigned long). So with that an unsigned > long variable cannot be used to store a pointer. > > To address both issues this series replaces the unsigned long variable > by an anonymous union containing both an unsigned long and a pointer. > > For all non-CHERI architectures this isn't an ABI change because all > have sizeof(void *) == sizeof(unsigned long). > > The first patch changes the definition of struct ieee1394_device_id. The > second drops some casts in sound drivers. (There are no other firewire > drivers that could benefit.) I adapted all sound drivers in a single > patch, tell me if I should split per driver. > > For merging I suggest to take the whole series via the ALSA tree in the > next merge window, as there are no modified files that are specific to > firewire only and the second patch depends on the first. > > Best regards > Uwe > > Uwe Kleine-König (The Capable Hub) (2): > firewire: Simplify storing pointers in device id struct > ALSA: firewire: Make use of ieee1394's .driver_data_ptr > > include/linux/mod_devicetable.h | 5 ++++- > sound/firewire/dice/dice.c | 34 ++++++++++++++++----------------- > sound/firewire/fireface/ff.c | 12 ++++++------ > sound/firewire/motu/motu.c | 6 +++--- > sound/firewire/oxfw/oxfw.c | 4 ++-- > 5 files changed, 32 insertions(+), 29 deletions(-) > > > base-commit: 028ef9c96e96197026887c0f092424679298aae8 > -- > 2.47.3 > |
|
From: Takashi S. <o-t...@sa...> - 2026-04-04 11:09:53
|
Hi, On Wed, Apr 01, 2026 at 05:32:39PM -0400, Dingisoul wrote: > Hi Takashi, > > Thank you for the quick reply! > > You are correct that the client_put() after the 'out' label, > releases the reference for the currently executing work. > > However, the reference leak happens in the pending work that > is canceled through cancel_delayed_work. Here is the detailed > analysis: > > CPU 0 (Executing) CPU 1 (Pending) > ------------- ------------ > schedule_iso_resource() > client_get() // get 1 > > iso_resource_work() > schedule_iso_resource() > client_get() // get 2 > > cancel_delayed_work() > client_put() // put 1 > > 1. First thread calls schedule_iso_resource. It calls client_get > (get 1) and queues r->work. > > 2. When first thread runs iso_resource_work, second thread calls > schedule_iso_resource again. It calls client_get (get 2) and > queues a new pending work item. > > 3. The first thread calls cancel_delayed_work which removes the > pending work from the queue. Because that work will never run, > the corresponding client_put after the 'out' label is never called. > > 4. The first thread call client_put (put 1) and finish the work. > > The reference acquired in step 2 is never put, causing a reference leak. > > Does this clarify the scenario? I'd be happy to provide more information. > > Thanks for your time! Now I got it. Indeed, we have the issue in current code. The work item could be accessible in several contexts by enumerating 'struct client.resourcew_xa'. The most probable scenario is the call of fw_cdev_update() when bus reset occurs. Hm. As a quick glance, I can not find a quick solution for this issue. Let me take more time to fix it (probably it requires code-refactoring). Thanks Takashi Sakamoto |
|
From: Takashi S. <o-t...@sa...> - 2026-04-01 06:57:57
|
Hi,
On Tue, Mar 31, 2026 at 03:48:18PM -0400, Dingisoul wrote:
> Hi Kernel maintainers,
>
> We found a possible refcount leak in iso_resource_work.
>
> When an iso_resource is being freed in iso_resource_work,
> cancel_delayed_work is called. If this call successfully
> cancels a pending work item, the client reference acquired
> when that work was scheduled is never released.
>
> static void schedule_iso_resource(struct iso_resource *r,
> unsigned long delay)
> {
> client_get(r->client); // 1. Reference taken
> if (!queue_delayed_work(fw_workqueue, &r->work, delay))
> client_put(r->client);
> }
>
>
> static void iso_resource_work(struct work_struct *work)
> {
> struct iso_resource *r = from_work(r, work, work.work);
> if (free) {
> cancel_delayed_work(&r->work); // 2. Potential leak
> kfree(r->e_alloc);
> kfree(r->e_dealloc);
> kfree(r);
> }
> }
We could see the "client_put()" at the line after "out" label.
$ git show v6.19:drivers/firewire/core-cdev.c | cat -n
...
1317 static void iso_resource_work(struct work_struct *work)
1318 {
...
1321 struct client *client = r->client;
...
(no return statements)
...
1401 if (free) {
1402 cancel_delayed_work(&r->work);
1403 kfree(r->e_alloc);
1404 kfree(r->e_dealloc);
1405 kfree(r);
1406 }
1407 out:
1408 client_put(client);
1409 }
I guess the above lines are not necessarily friendly to any of your
tools. I would be glad to receive any patches or ideas inspired by your
testing mindset.
Thanks
Takashi Sakamoto
|
|
From: Takashi S. <o-t...@sa...> - 2026-03-30 01:11:48
|
Hi, Thanks for sending your patch. On Sun, Mar 29, 2026 at 11:19:40PM +0200, Thorsten Blum wrote: > Use scnprintf() in get_modalias() to return the number of characters > actually written to the destination buffer. > > Also reserve space for the trailing newline in modalias_show() and > append it explicitly, instead of using strcpy() and relying on the > formatted modalias to fit within PAGE_SIZE. > > While the current code is safe, this makes the sysfs buffer handling > more explicit and consistent. > > Signed-off-by: Thorsten Blum <tho...@li...> > --- > drivers/firewire/core-device.c | 11 ++++++----- > 1 file changed, 6 insertions(+), 5 deletions(-) I previously considered using sysfs_emit(_at)() in the code, but decided against it because the code is called in both sysfs and the workqueue context of firewire devices. The buffer size differs between these cases (either PAGE_SIZE or 64). In any case, as you already noted, the current code is enough safe. The total length of formatted string is fixed (= 41 + 1) by the format template, so it is unlikely to cause issues. I have little motivation to change it. Thanks Takashi Sakamoto |
|
From: Takashi S. <o-t...@sa...> - 2026-03-01 03:04:18
|
Hi Linus, Please apply a single fix for 1394 OHCI PCI driver. The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f: Linux 7.0-rc1 (2026-02-22 13:18:59 -0800) are available in the Git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394.git tags/firewire-fixes-7.0-rc2 for you to fetch changes up to 7b7a12aec17d5605678e9d170faf8ba3e9f9e42c: firewire: ohci: initialize page array to use alloc_pages_bulk() correctly (2026-03-01 11:43:28 +0900) ---------------------------------------------------------------- firewire fixes for 7.0-rc2 Fix a bug to pass uninitialized pointer for page structure to vmap(). The bug was reported by John Ogness with PowerMac7,2 (ppc64be machine) and could be regenerated in the other types of machines. ---------------------------------------------------------------- Takashi Sakamoto (1): firewire: ohci: initialize page array to use alloc_pages_bulk() correctly drivers/firewire/ohci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Regards Takashi Sakamoto |
|
From: Takashi S. <o-t...@sa...> - 2026-02-28 03:13:08
|
Hi,
Thanks for the issue. It reports that the page array passed to vmap()
includes any entries which have invalid PFN. I realize that the page
array is passed to page_alloc_bulk() without zero initialization, thus
it could include any garbage values.
Would I ask you to apply the following patch and the issue is still
regenerated or not?
===== 8<- -----
>From 0d82ddae99869b231200d5247bbae586bf28274c Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-t...@sa...>
Date: Sat, 28 Feb 2026 11:56:03 +0900
Subject: [PATCH] firewire: ohci: initialize page array to use
alloc_pages_bulk() correctly
The call of alloc_pages_bulk() skips to fill entries of page array when
the entries already have values. While, 1394 OHCI PCI driver passes the
page array without initializing. It could cause invalid state at PFN
validation in vmap().
Fixes: f2ae92780ab9 ("firewire: ohci: split page allocation from dma mapping")
Reported-by: John Ogness <joh...@li...>
Closes: https://lore.kernel.org/lkml/87t...@jo.../
Signed-off-by: Takashi Sakamoto <o-t...@sa...>
---
drivers/firewire/ohci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 1c868c1e..8153d62c 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -848,7 +848,7 @@ static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci,
{
struct device *dev = ohci->card.device;
unsigned int i;
- struct page *pages[AR_BUFFERS + AR_WRAPAROUND_PAGES];
+ struct page *pages[AR_BUFFERS + AR_WRAPAROUND_PAGES] = { NULL };
dma_addr_t dma_addrs[AR_BUFFERS];
void *vaddr;
struct descriptor *d;
--
2.51.0
===== 8<- -----
Thanks
Takashi Sakamoto
On Sat, Feb 28, 2026 at 01:13:54AM +0106, John Ogness wrote:
> Hi,
>
> With 7.0.0-rc1 I am seeing 2 warnings and a crash when loading the
> firewire-ohci module.
>
> I will not have time to debug this for a couple weeks. But maybe it is
> already obvious to some of the firewire folks.
>
> This is a ppc64be machine (4k pages).
>
> John Ogness
>
> Following is the kernel log when running:
>
> # insmod ./firewire-ohci.ko
>
> [ 71.072914][ T1781] firewire_ohci 0001:03:0e.0: enabling device (0000 -> 0002)
> [ 71.075242][ T1781] ------------[ cut here ]------------
> [ 71.075439][ T1781] WARNING: [] mm/vmalloc.c:554 at .vmap_small_pages_range_noflush+0x354/0x558, CPU#0: insmod/1781
> [ 71.075696][ T1781] Modules linked in: firewire_ohci(+) firewire_core netconsole 8021q garp stp mrp llc nouveau drm_ttm_helper ttm gpu_sched drm_client_lib i2c_algo_bit drm_display_helper drm_kms_helper drm_gpuvm drm_exec drm drm_panel_orientation_quirks windfarm_smu_sat binfmt_misc b43 rng_core cordic bcma mac80211 libarc4 windfarm_cpufreq_clamp cfg80211 snd_aoa_codec_tas snd_aoa_fabric_layout windfarm_pm72 snd_aoa windfarm_pid rfkill windfarm_max6690_sensor windfarm_fcu_controls windfarm_ad7417_sensor windfarm_lm75_sensor windfarm_core snd_aoa_i2sbus snd_aoa_soundbus snd_pcm joydev mousedev snd_timer mac_hid ssb snd soundcore rack_meter mmc_core uninorth_agp agpgart
> [ 71.094003][ T1781] CPU: 0 UID: 0 PID: 1781 Comm: insmod Not tainted 7.0.0-rc1 #2 PREEMPT
> [ 71.097990][ T1781] Hardware name: PowerMac7,2 PPC970 0x390202 PowerMac
> [ 71.102043][ T1781] NIP: c00000000052e074 LR: c00000000052e128 CTR: c00000000bd7c880
> [ 71.106208][ T1781] REGS: c00000000dee6a10 TRAP: 0700 Not tainted (7.0.0-rc1)
> [ 71.110505][ T1781] MSR: 900000000202b032 <SF,HV,VEC,EE,FP,ME,IR,DR,RI> CR: 84008448 XER: 20000000
> [ 71.115002][ T1781] IRQMASK: 0
> [ 71.115002][ T1781] GPR00: c00000000052e128 c00000000dee6cb0 c000000001b7f100 ffffff04002a72e6
> [ 71.115002][ T1781] GPR04: c00000000052e128 c0003d00015eafff ffffffffffffffff ffffffffffffffff
> [ 71.115002][ T1781] GPR08: 0000000000000000 000fff04002a72e6 0000000000000000 0000000000000003
> [ 71.115002][ T1781] GPR12: 0000000024008442 c000000003ca5000 c0003d00015e1000 c00000000a9cb988
> [ 71.115002][ T1781] GPR16: c000000002da2dc0 c00000000c7eaf08 c00000000dee6f48 ee1fffffffffffbf
> [ 71.115002][ T1781] GPR20: c000000004042000 800000000000018e c000000002b82d80 c0003d00015eb000
> [ 71.115002][ T1781] GPR24: c000000002da2e58 0000000000000001 0000000000000001 c0003d00015eafff
> [ 71.115002][ T1781] GPR28: c00000000a415b80 0000000000000000 c0003d00015eb000 c00000000403f050
> [ 71.156263][ T1781] NIP [c00000000052e074] .vmap_small_pages_range_noflush+0x354/0x558
> [ 71.160879][ T1781] LR [c00000000052e128] .vmap_small_pages_range_noflush+0x408/0x558
> [ 71.165656][ T1781] Call Trace:
> [ 71.170546][ T1781] [c00000000dee6cb0] [c00000000052e128] .vmap_small_pages_range_noflush+0x408/0x558 (unreliable)
> [ 71.175967][ T1781] [c00000000dee6de0] [c0000000005357d0] .vmap+0xd4/0x1a8
> [ 71.181890][ T1781] [c00000000dee6e90] [c0003d00010f1e64] .ar_context_init+0xfc/0x38c [firewire_ohci]
> [ 71.187978][ T1781] [c00000000dee6fe0] [c0003d00010f5378] .pci_probe+0x25c/0x8c0 [firewire_ohci]
> [ 71.194098][ T1781] [c00000000dee70b0] [c000000000c6ad64] .pci_device_probe+0x108/0x26c
> [ 71.200284][ T1781] [c00000000dee7140] [c000000000d5ecc8] .really_probe+0x110/0x564
> [ 71.206420][ T1781] [c00000000dee71e0] [c000000000d5f1c8] .__driver_probe_device+0xac/0x1ec
> [ 71.212222][ T1781] [c00000000dee7270] [c000000000d5f468] .driver_probe_device+0x5c/0x120
> [ 71.217586][ T1781] [c00000000dee7300] [c000000000d5f928] .__driver_attach+0x1e8/0x384
> [ 71.222495][ T1781] [c00000000dee7390] [c000000000d5b3c8] .bus_for_each_dev+0xac/0x12c
> [ 71.227382][ T1781] [c00000000dee7440] [c000000000d5e274] .driver_attach+0x34/0x4c
> [ 71.232111][ T1781] [c00000000dee74c0] [c000000000d5d5b8] .bus_add_driver+0x2a0/0x334
> [ 71.236656][ T1781] [c00000000dee7560] [c000000000d60d8c] .driver_register+0x84/0x1b8
> [ 71.241063][ T1781] [c00000000dee75e0] [c000000000c698e4] .__pci_register_driver+0x8c/0xac
> [ 71.245385][ T1781] [c00000000dee7670] [c0003d00010f6ea4] .fw_ohci_init+0x30/0x44 [firewire_ohci]
> [ 71.249706][ T1781] [c00000000dee76e0] [c00000000000ef58] .do_one_initcall+0x8c/0x5d4
> [ 71.254172][ T1781] [c00000000dee77e0] [c00000000021aae4] .do_init_module+0x70/0x33c
> [ 71.258857][ T1781] [c00000000dee7870] [c00000000021de5c] .init_module_from_file+0x110/0x134
> [ 71.263662][ T1781] [c00000000dee79a0] [c00000000021e0ec] .idempotent_init_module+0x26c/0x34c
> [ 71.268466][ T1781] [c00000000dee7af0] [c00000000021e270] .__se_sys_finit_module+0xa4/0x188
> [ 71.273142][ T1781] [c00000000dee7ba0] [c00000000002b73c] .system_call_exception+0x16c/0x280
> [ 71.277757][ T1781] [c00000000dee7e10] [c00000000000b754] system_call_common+0xf4/0x258
> [ 71.282285][ T1781] ---- interrupt: c00 at 0x3fff90945174
> [ 71.286856][ T1781] NIP: 00003fff90945174 LR: 0000000117b6d338 CTR: 0000000000000000
> [ 71.291455][ T1781] REGS: c00000000dee7e80 TRAP: 0c00 Not tainted (7.0.0-rc1)
> [ 71.296087][ T1781] MSR: 900000000200f032 <SF,HV,VEC,EE,PR,FP,ME,IR,DR,RI> CR: 20000202 XER: 00000000
> [ 71.300895][ T1781] IRQMASK: 0
> [ 71.300895][ T1781] GPR00: 0000000000000161 00003ffff63304b0 00003fff909f0e00 0000000000000003
> [ 71.300895][ T1781] GPR04: 0000000117b7a6f8 0000000000000000 0000000000000000 0000000000000000
> [ 71.300895][ T1781] GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> [ 71.300895][ T1781] GPR12: 0000000000000000 00003fff909f2d28 0000000000000000 0000000000000000
> [ 71.300895][ T1781] GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000080000000
> [ 71.300895][ T1781] GPR20: 0000000000000001 0000000000000000 0000000000000000 00003ffff63317c4
> [ 71.300895][ T1781] GPR24: 00003ffff6330800 0000000117b7b788 00003fff907ee870 0000000117b7a6f8
> [ 71.300895][ T1781] GPR28: 0000000000000000 0000000000000000 00003fff907eef50 00003ffff63304b0
> [ 71.339126][ T1781] NIP [00003fff90945174] 0x3fff90945174
> [ 71.342757][ T1781] LR [0000000117b6d338] 0x117b6d338
> [ 71.346372][ T1781] ---- interrupt: c00
> [ 71.349938][ T1781] Code: 7929d182 0b090000 2c2f0000 4182ffd0 3d220122 3a093cc0 e9300000 7d297850 7d233674 7929d302 7c234800 41820010 <0fe00000> 4bfff661 4bffffb4 4bfff969
> [ 71.357572][ T1781] irq event stamp: 0
> [ 71.361401][ T1781] hardirqs last enabled at (0): [<0000000000000000>] 0x0
> [ 71.365343][ T1781] hardirqs last disabled at (0): [<c0000000000e938c>] .copy_process+0x9e4/0x2128
> [ 71.369291][ T1781] softirqs last enabled at (0): [<c0000000000e938c>] .copy_process+0x9e4/0x2128
> [ 71.373188][ T1781] softirqs last disabled at (0): [<0000000000000000>] 0x0
> [ 71.377087][ T1781] ---[ end trace 0000000000000000 ]---
> [ 71.393853][ T1781] ------------[ cut here ]------------
> [ 71.397878][ T1781] WARNING: [(unsigned long)v & mask] include/linux/instrumented.h:67 at .folios_put_refs+0x118/0x248, CPU#1: insmod/1781
> [ 71.406168][ T1781] Modules linked in: firewire_ohci(+) firewire_core netconsole 8021q garp stp mrp llc nouveau drm_ttm_helper ttm gpu_sched drm_client_lib i2c_algo_bit drm_display_helper drm_kms_helper drm_gpuvm drm_exec drm drm_panel_orientation_quirks windfarm_smu_sat binfmt_misc b43 rng_core cordic bcma mac80211 libarc4 windfarm_cpufreq_clamp cfg80211 snd_aoa_codec_tas snd_aoa_fabric_layout windfarm_pm72 snd_aoa windfarm_pid rfkill windfarm_max6690_sensor windfarm_fcu_controls windfarm_ad7417_sensor windfarm_lm75_sensor windfarm_core snd_aoa_i2sbus snd_aoa_soundbus snd_pcm joydev mousedev snd_timer mac_hid ssb snd soundcore rack_meter mmc_core uninorth_agp agpgart
> [ 71.433394][ T1781] CPU: 1 UID: 0 PID: 1781 Comm: insmod Tainted: G W 7.0.0-rc1 #2 PREEMPT
> [ 71.437972][ T1781] Tainted: [W]=WARN
> [ 71.442535][ T1781] Hardware name: PowerMac7,2 PPC970 0x390202 PowerMac
> [ 71.447736][ T1781] NIP: c0000000004a64a4 LR: c0000000004a69ec CTR: c0000000004a688c
> [ 71.453273][ T1781] REGS: c00000000dee6910 TRAP: 0700 Tainted: G W (7.0.0-rc1)
> [ 71.459350][ T1781] MSR: 900000000202b032 <SF,HV,VEC,EE,FP,ME,IR,DR,RI> CR: 44008842 XER: 20000000
> [ 71.465678][ T1781] IRQMASK: 0
> [ 71.465678][ T1781] GPR00: c0000000004a69ec c00000000dee6bb0 c000000001b7f100 c00000000dee6d68
> [ 71.465678][ T1781] GPR04: c00000000dee6cec c00000000dee6e70 c000000007295238 0000000000000007
> [ 71.465678][ T1781] GPR08: 0000000000000000 0000000000000001 0000a2f612000042 c0003d00010f7508
> [ 71.465678][ T1781] GPR12: 0000000044008842 c00000000ffff700 0000000000000000 0000000000000000
> [ 71.465678][ T1781] GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000080000000
> [ 71.465678][ T1781] GPR20: 0000000000000001 0000000000000000 0000000000000000 c0000000038b1bb0
> [ 71.465678][ T1781] GPR24: 0000000000000000 c0003d000126a348 c00000000dee6cec 0000000000000000
> [ 71.465678][ T1781] GPR28: c00000000dee6d68 ffffffff815f0997 0000000000000006 0000a2f61200000e
> [ 71.521625][ T1781] NIP [c0000000004a64a4] .folios_put_refs+0x118/0x248
> [ 71.526860][ T1781] LR [c0000000004a69ec] .release_pages+0x160/0x17c
> [ 71.531889][ T1781] Call Trace:
> [ 71.536976][ T1781] [c00000000dee6bb0] [c0000001ff9b2808] 0xc0000001ff9b2808 (unreliable)
> [ 71.542101][ T1781] [c00000000dee6c70] [c0000000004a69ec] .release_pages+0x160/0x17c
> [ 71.752192][ T1781] BUG: Unable to handle kernel data access at 0xa2f612000042
> [ 71.756852][ T1781] Faulting instruction address: 0xc0000000004a6418
> [ 71.761078][ T1781] Oops: Kernel access of bad area, sig: 11 [#1]
> [ 71.765026][ T1781] BE PAGE_SIZE=4K MMU=Hash SMP NR_CPUS=2 PowerMac
> [ 71.769033][ T1781] Modules linked in: firewire_ohci(+) firewire_core netconsole 8021q garp stp mrp llc nouveau drm_ttm_helper ttm gpu_sched drm_client_lib i2c_algo_bit drm_display_helper drm_kms_helper drm_gpuvm drm_exec drm drm_panel_orientation_quirks windfarm_smu_sat binfmt_misc b43 rng_core cordic bcma mac80211 libarc4 windfarm_cpufreq_clamp cfg80211 snd_aoa_codec_tas snd_aoa_fabric_layout windfarm_pm72 snd_aoa windfarm_pid rfkill windfarm_max6690_sensor windfarm_fcu_controls windfarm_ad7417_sensor windfarm_lm75_sensor windfarm_core snd_aoa_i2sbus snd_aoa_soundbus snd_pcm joydev mousedev snd_timer mac_hid ssb snd soundcore rack_meter mmc_core uninorth_agp agpgart
> [ 71.795478][ T1781] CPU: 1 UID: 0 PID: 1781 Comm: insmod Tainted: G W 7.0.0-rc1 #2 PREEMPT
> [ 71.800475][ T1781] Tainted: [W]=WARN
> [ 71.805735][ T1781] Hardware name: PowerMac7,2 PPC970 0x390202 PowerMac
> [ 71.811373][ T1781] NIP: c0000000004a6418 LR: c0000000004a69ec CTR: c0000000004a688c
> [ 71.817080][ T1781] REGS: c00000000dee6910 TRAP: 0380 Tainted: G W (7.0.0-rc1)
> [ 71.822893][ T1781] MSR: 900000000200b032 <SF,HV,VEC,EE,FP,ME,IR,DR,RI> CR: 44008842 XER: 20000000
> [ 71.828920][ T1781] IRQMASK: 0
> [ 71.828920][ T1781] GPR00: c0000000004a69ec c00000000dee6bb0 c000000001b7f100 c00000000dee6d68
> [ 71.828920][ T1781] GPR04: c00000000dee6cec c00000000dee6e70 c000000007295238 0000000000000007
> [ 71.828920][ T1781] GPR08: 0000000000000000 0000000000000001 0000a2f612000042 c0003d00010f7508
> [ 71.828920][ T1781] GPR12: 0000000044008842 c00000000ffff700 0000000000000000 0000000000000000
> [ 71.828920][ T1781] GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000080000000
> [ 71.828920][ T1781] GPR20: 0000000000000001 0000000000000000 0000000000000000 c0000000038b1bb0
> [ 71.828920][ T1781] GPR24: 0000000000000000 c0003d000126a348 c00000000dee6cec 0000000000000000
> [ 71.828920][ T1781] GPR28: c00000000dee6d68 ffffffff815f0997 0000000000000006 0000a2f61200000e
> [ 71.876903][ T1781] NIP [c0000000004a6418] .folios_put_refs+0x8c/0x248
> [ 71.881518][ T1781] LR [c0000000004a69ec] .release_pages+0x160/0x17c
> [ 71.886162][ T1781] Call Trace:
> [ 71.890705][ T1781] [c00000000dee6bb0] [c0000001ff9b2808] 0xc0000001ff9b2808 (unreliable)
> [ 71.895389][ T1781] [c00000000dee6c70] [c0000000004a69ec] .release_pages+0x160/0x17c
> [ 71.900095][ T1781] [c00000000dee6e90] [c0003d00010f20d0] .ar_context_init+0x368/0x38c [firewire_ohci]
> [ 71.904914][ T1781] [c00000000dee6fe0] [c0003d00010f5378] .pci_probe+0x25c/0x8c0 [firewire_ohci]
> [ 71.909699][ T1781] [c00000000dee70b0] [c000000000c6ad64] .pci_device_probe+0x108/0x26c
> [ 71.914467][ T1781] [c00000000dee7140] [c000000000d5ecc8] .really_probe+0x110/0x564
> [ 71.919165][ T1781] [c00000000dee71e0] [c000000000d5f1c8] .__driver_probe_device+0xac/0x1ec
> [ 71.923876][ T1781] [c00000000dee7270] [c000000000d5f468] .driver_probe_device+0x5c/0x120
> [ 71.928536][ T1781] [c00000000dee7300] [c000000000d5f928] .__driver_attach+0x1e8/0x384
> [ 71.933089][ T1781] [c00000000dee7390] [c000000000d5b3c8] .bus_for_each_dev+0xac/0x12c
> [ 71.937524][ T1781] [c00000000dee7440] [c000000000d5e274] .driver_attach+0x34/0x4c
> [ 71.941789][ T1781] [c00000000dee74c0] [c000000000d5d5b8] .bus_add_driver+0x2a0/0x334
> [ 71.945940][ T1781] [c00000000dee7560] [c000000000d60d8c] .driver_register+0x84/0x1b8
> [ 71.949921][ T1781] [c00000000dee75e0] [c000000000c698e4] .__pci_register_driver+0x8c/0xac
> [ 71.953800][ T1781] [c00000000dee7670] [c0003d00010f6ea4] .fw_ohci_init+0x30/0x44 [firewire_ohci]
> [ 71.957583][ T1781] [c00000000dee76e0] [c00000000000ef58] .do_one_initcall+0x8c/0x5d4
> [ 71.961314][ T1781] [c00000000dee77e0] [c00000000021aae4] .do_init_module+0x70/0x33c
> [ 71.965033][ T1781] [c00000000dee7870] [c00000000021de5c] .init_module_from_file+0x110/0x134
> [ 71.968674][ T1781] [c00000000dee79a0] [c00000000021e0ec] .idempotent_init_module+0x26c/0x34c
> [ 71.972301][ T1781] [c00000000dee7af0] [c00000000021e270] .__se_sys_finit_module+0xa4/0x188
> [ 71.975866][ T1781] [c00000000dee7ba0] [c00000000002b73c] .system_call_exception+0x16c/0x280
> [ 71.979337][ T1781] [c00000000dee7e10] [c00000000000b754] system_call_common+0xf4/0x258
> [ 71.982732][ T1781] ---- interrupt: c00 at 0x3fff90945174
> [ 71.986164][ T1781] NIP: 00003fff90945174 LR: 0000000117b6d338 CTR: 0000000000000000
> [ 71.989622][ T1781] REGS: c00000000dee7e80 TRAP: 0c00 Tainted: G W (7.0.0-rc1)
> [ 71.993162][ T1781] MSR: 900000000200f032 <SF,HV,VEC,EE,PR,FP,ME,IR,DR,RI> CR: 20000202 XER: 00000000
> [ 71.996866][ T1781] IRQMASK: 0
> [ 71.996866][ T1781] GPR00: 0000000000000161 00003ffff63304b0 00003fff909f0e00 0000000000000003
> [ 71.996866][ T1781] GPR04: 0000000117b7a6f8 0000000000000000 0000000000000000 0000000000000000
> [ 71.996866][ T1781] GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> [ 71.996866][ T1781] GPR12: 0000000000000000 00003fff909f2d28 0000000000000000 0000000000000000
> [ 71.996866][ T1781] GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000080000000
> [ 71.996866][ T1781] GPR20: 0000000000000001 0000000000000000 0000000000000000 00003ffff63317c4
> [ 71.996866][ T1781] GPR24: 00003ffff6330800 0000000117b7b788 00003fff907ee870 0000000117b7a6f8
> [ 71.996866][ T1781] GPR28: 0000000000000000 0000000000000000 00003fff907eef50 00003ffff63304b0
> [ 72.029204][ T1781] NIP [00003fff90945174] 0x3fff90945174
> [ 72.032647][ T1781] LR [0000000117b6d338] 0x117b6d338
> [ 72.036099][ T1781] ---- interrupt: c00
> [ 72.039484][ T1781] Code: 3bc00000 fba100a8 fbe100b8 3b600000 48000088 60000000 73ea0003 7bc91764 395f0034 7d3a4aaa 40820094 7c0004ac <7fa05028> 7fa9e810 7fa0512d 40c2fff4
> [ 72.046718][ T1781] ---[ end trace 0000000000000000 ]---
> [ 72.050575][ T1781]
> [ 73.044412][ T1781] Kernel panic - not syncing: Fatal exception
> [ 73.047957][ T1781] ---[ end Kernel panic - not syncing: Fatal exception ]---
|
|
From: Takashi S. <o-t...@sa...> - 2026-02-11 05:29:02
|
Hi Linus,
(C.C.ed to linux-sound, Jens Wiklander, and Jason Gunthorpe)
Please pull firewire changes for 7.0. It includes the following changes:
- Refactor page allocation dedicated to 1394 OHCI IR/IT/AR DMA contexts
- Allocate variable-sized buffer for isochronous context header
- Including a small change in sound subsystem
This subsystem has been a long-standing, single user of dma_alloc_pages().
Recently, TEE subsystem added usage in a commit
ab09dd6d9201 ("tee: add tee_shm_alloc_dma_mem()"), and it still remains.
I think the kernel API can be avoided in direct calls and encapsulated for
the convenience of DMA mapping layer developers.
Thanks
Takashi Sakamoto
(on a national holiday in Japan)
---
The following changes since commit 8f0b4cce4481fb22653697cced8d0d04027cb1e8:
Linux 6.19-rc1 (2025-12-14 16:05:07 +1200)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394.git tags/firewire-updates-7.0
for you to fetch changes up to 6b617317e5bc95e9962a712314ae0c4b7a4d5cc3:
ALSA: firewire: remove PCM buffer size constraint from isoc context header (2026-01-18 17:18:48 +0900)
----------------------------------------------------------------
firewire updates for v7.0
This update includes the following changes.
- Refactor page allocation dedicated to 1394 OHCI IR/IT/AR DMA contexts
Although 1394 OHCI specification does not impose any restriction on
the memory size dedicated to these DMA contexts, 1394 OHCI PCI driver
allocates pages for convenience when mapping them into either kernel
space or userspace VMA. The driver previously used dma_alloc_pages()
for both page allocation and mapping creation, even though this kernel
API is rarely used. Following discussions questioning the page-oriented
kernel API in the DMA layer, the driver has been refactored to avoid
using this API. In addition, the use of private members in the
allocated pages has been removed following long-standing concern.
- Allocate variable-sized buffer for isochronous context header
1394 OHCI PCI driver previously allocated a single page for isochronous
context header. As a result, the buffer size for the header was fixed
to PAGE_SIZE, which imposed a limitation on IEC 61883-1/6 packet
streaming engine. Consequently, the ALSA PCM devices provided by
drivers for audio and music units in IEEE 1394 bus were constrained in
the maximum size of buffer period (64 ms in most cases). This limitation
is resolved by dynamically allocating the header buffer with an
arbitrary size.
----------------------------------------------------------------
Takashi Sakamoto (18):
firewire: core: move private function declaration from public header to internal header
firewire: core: use mutex instead of spinlock for client isochronous context
firewire: core: code refactoring with cleanup function for isoc pages
firewire: core: use common kernel API to allocate and release a batch of pages
firewire: core: stop using page private to store DMA mapping address
firewire: ohci: use MAX macro to guarantee minimum count of pages for AR contexts
firewire: ohci: split page allocation from dma mapping
firewire: ohci: stop using page private to store DMA mapping address
firewire: ohci: fix index of pages for dma address to 1394 OHCI IT context
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 | 71 +++++--------
drivers/firewire/core-iso.c | 102 +++++++++---------
drivers/firewire/core.h | 14 ++-
drivers/firewire/ohci.c | 234 ++++++++++++++++++++++++------------------
include/linux/firewire.h | 36 +++++--
sound/firewire/amdtp-stream.c | 31 ++----
7 files changed, 266 insertions(+), 226 deletions(-)
|
|
From: Takashi S. <o-t...@sa...> - 2026-02-05 12:37:41
|
Hi, > Rpnpif, reported in Debian (at https://bugs.debian.org/1126090) that > firewire_ohci driver has since almost 3.16, an issue with the > following device: Thanks for your report[1]. > 01:00.0 PCI bridge [0604]: Texas Instruments XIO2213A/B/XIO2221 PCI Express to PCI Bridge [Cheetah Express] [104c:823e] (rev 01) (prog-if 00 [Normal decode]) > Subsystem: Device [3412:7856] > Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- > Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- > Latency: 0, Cache Line Size: 64 bytes > IOMMU group: 1 > Region 1: Memory at fe700000 (32-bit, non-prefetchable) [size=4K] > Bus: primary=01, secondary=02, subordinate=02, sec-latency=32 > I/O behind bridge: [disabled] [32-bit] > Memory behind bridge: fe600000-fe6fffff [size=1M] [32-bit] > Prefetchable memory behind bridge: [disabled] [64-bit] > Secondary status: 66MHz+ FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- <SERR- <PERR- > BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16+ MAbort- >Reset- FastB2B- > PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn- > Capabilities: <access denied> > > 02:00.0 FireWire (IEEE 1394) [0c00]: Texas Instruments XIO2213A/B/XIO2221 IEEE-1394b OHCI Controller [Cheetah Express] [104c:823f] (rev 01) (prog-if 10 [OHCI]) > Subsystem: Device [3412:7856] > Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- > Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- > Interrupt: pin A routed to IRQ 18 > IOMMU group: 1 > Region 0: Memory at fe604000 (32-bit, non-prefetchable) [size=2K] > Region 1: Memory at fe600000 (32-bit, non-prefetchable) [size=16K] > Capabilities: <access denied> > Kernel modules: firewire_ohci I use so long the similar product with the same combination of bus bridge chip and 1394 OHCI controller, on AMD processor family 19th model 0x50 (Ryzen 7 5700G, Cezanne), but never face the issue. My output of lspci is: ``` $ lspci -vnn ... 01:00.0 PCI bridge [0604]: Texas Instruments XIO2213A/B/XIO2221 PCI Express to PCI Bridge [Cheetah Express] [104c:823e] (rev 01) (prog-if 00 [Normal decode]) Subsystem: Texas Instruments Device [104c:823f] Flags: bus master, fast devsel, latency 0, IOMMU group 10 Memory at fcd00000 (32-bit, non-prefetchable) [size=4K] Bus: primary=01, secondary=02, subordinate=02, sec-latency=32 I/O behind bridge: [disabled] [32-bit] Memory behind bridge: fcc00000-fccfffff [size=1M] [32-bit] Prefetchable memory behind bridge: [disabled] [64-bit] Capabilities: <access denied> 02:00.0 FireWire (IEEE 1394) [0c00]: Texas Instruments XIO2213A/B/XIO2221 IEEE-1394b OHCI Controller [Cheetah Express] [104c:823f] (rev 01) (prog-if 10 [OHCI]) Subsystem: Texas Instruments XIO2213A/B/XIO2221 IEEE-1394b OHCI Controller [Cheetah Express] [104c:823f] Flags: bus master, 66MHz, medium devsel, latency 32, IRQ 121, IOMMU group 10 Memory at fcc04000 (32-bit, non-prefetchable) [size=2K] Memory at fcc00000 (32-bit, non-prefetchable) [size=16K] Capabilities: <access denied> Kernel driver in use: firewire_ohci Kernel modules: firewire_ohci ... ``` According to the value of subsystem field, it is manufactured by Texas Instruments, while the issued device is from 3412:7856. The vendor ID 0x3412 seems not to be registered in pciids[2]. Fortunately, I can find the report from Raspberry PI users to use the device[3], and it seems to work in their Arm64 machine. I guess that the issue appears in the case to use a certain combination of hardware. I can remember an unresolved issue that AMD Ryzen machine generates unexpected system reboot when working with the hardware of ASM1083 and VT63xx[4], but never cleared. > [ 14.149170] Call Trace: > [ 14.149174] <TASK> > [ 14.149177] dump_stack_lvl+0x64/0x80 > [ 14.149185] read_phy_reg+0x91/0xa0 [firewire_ohci] > [ 14.149196] ohci_enable+0x3a3/0x5b0 [firewire_ohci] > [ 14.149204] fw_card_add+0x85/0x110 [firewire_core] > [ 14.149232] pci_probe+0x492/0x620 [firewire_ohci] > ... > [ 14.149364] </TASK> > [ 14.150242] firewire_ohci 0000:02:00.0: probe with driver firewire_ohci failed with error -16 > [ 14.150382] firewire_ohci 0000:02:00.0: removed fw-ohci device The above messages are printed by the following line: $ git show v6.12:drivers/firewire/ohci.c | nl -b a 634 static int read_phy_reg(struct fw_ohci *ohci, int addr) 635 { 636 u32 val; 637 int i; 638 639 reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); 640 for (i = 0; i < 3 + 100; i++) { 641 val = reg_read(ohci, OHCI1394_PhyControl); 642 if (!~val) 643 return -ENODEV; /* Card was ejected. */ 644 645 if (val & OHCI1394_PhyControl_ReadDone) 646 return OHCI1394_PhyControl_ReadData(val); 647 648 /* 649 * Try a few times without waiting. Sleeping is necessary 650 * only when the link/PHY interface is busy. 651 */ 652 if (i >= 3) 653 msleep(1); 654 } 655 ohci_err(ohci, "failed to read phy reg %d\n", addr); 656 dump_stack(); 657 658 return -EBUSY; 659 } It hits 'dump_stack()'. It means that it has no critical effect to your running machine, just generates annoying dump message, So our situation is not so critical, in system POV. The cause is that the value of register does not become to have a 'done' bit, even if retrying 100 times, after configuring the link layer to read register in PHY layer. The most suspicious cause is the hardware fail to provide SCLK signal even after turning on Link Power Status (LPS). In this case, any access to the OHCI1394_PhyControl register undefined, according to 1394 OHCI Specification Release 1.1 (clause 4. Register addressing). Actually the 1394 OHCI driver attempts to detect LPS-on by the following lines: ``` 2416 static int ohci_enable(struct fw_card *card, 2417 const __be32 *config_rom, size_t length) 2418 { ... 2442 reg_write(ohci, OHCI1394_HCControlSet, 2443 OHCI1394_HCControl_LPS | 2444 OHCI1394_HCControl_postedWriteEnable); 2445 flush_writes(ohci); 2446 2447 for (lps = 0, i = 0; !lps && i < 3; i++) { 2448 msleep(50); 2449 lps = reg_read(ohci, OHCI1394_HCControlSet) & 2450 OHCI1394_HCControl_LPS; 2451 } 2452 2453 if (!lps) { 2454 ohci_err(ohci, "failed to set Link Power Status\n"); 2455 return -EIO; 2456 } ... ``` On the other hand, the arrival of SCLK can not detected by software. Would I ask you to try inserting msleep() with enough long in the end of the above lines if you can compile the driver code by yourself? [1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1126090 [2] https://pci-ids.ucw.cz/ [3] https://github.com/geerlingguy/raspberry-pi-pcie-devices/issues/297 [4] https://lore.kernel.org/lkml/202...@wo.../ Regards Takashi Sakamoto |
|
From: Takashi S. <o-t...@sa...> - 2026-01-30 22:54:41
|
Hi Linus, Please accept the following changes to fix a race condition introduced in v6.18 kernel. The following changes since commit 20e01bba2ae4898ce65cdcacd1bd6bec5111abd9: firewire: core: fix race condition against transaction list (2026-01-29 08:03:55 +0900) are available in the Git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394.git for-linus for you to fetch changes up to 20e01bba2ae4898ce65cdcacd1bd6bec5111abd9: firewire: core: fix race condition against transaction list (2026-01-29 08:03:55 +0900) ---------------------------------------------------------------- Regards Takashi Sakamoto |
|
From: Takashi S. <o-t...@sa...> - 2026-01-28 23:07:05
|
On Wed, Jan 28, 2026 at 07:34:13AM +0900, Takashi Sakamoto wrote:
> The list of transaction is enumerated without acquiring card lock when
> processing AR response event. This causes a race condition bug when
> processing AT request completion event concurrently.
>
> This commit fixes the bug by put timer start for split transaction
> expiration into the scope of lock. The value of jiffies in card structure
> is referred before acquiring the lock.
>
> Cc: st...@vg... # v6.18
> Fixes: b5725cfa4120 ("firewire: core: use spin lock specific to timer for split transaction")
> Reported-by: Andreas Persson <and...@ou...>
> Closes: https://github.com/alsa-project/snd-firewire-ctl-services/issues/209
> Tested-by: Andreas Persson <and...@ou...>
> Signed-off-by: Takashi Sakamoto <o-t...@sa...>
> ---
> drivers/firewire/core-transaction.c | 19 ++++++++++---------
> 1 file changed, 10 insertions(+), 9 deletions(-)
Applied to for-linus branch. I'll send it to mainline in this weekend in
time for v6.19-rc8 release.
Regards
Takashi Sakamoto
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-27 22:34:26
|
The list of transaction is enumerated without acquiring card lock when
processing AR response event. This causes a race condition bug when
processing AT request completion event concurrently.
This commit fixes the bug by put timer start for split transaction
expiration into the scope of lock. The value of jiffies in card structure
is referred before acquiring the lock.
Cc: st...@vg... # v6.18
Fixes: b5725cfa4120 ("firewire: core: use spin lock specific to timer for split transaction")
Reported-by: Andreas Persson <and...@ou...>
Closes: https://github.com/alsa-project/snd-firewire-ctl-services/issues/209
Tested-by: Andreas Persson <and...@ou...>
Signed-off-by: Takashi Sakamoto <o-t...@sa...>
---
drivers/firewire/core-transaction.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 7fea11a5e359..22ae387ae03c 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -173,20 +173,14 @@ static void split_transaction_timeout_callback(struct timer_list *timer)
}
}
-static void start_split_transaction_timeout(struct fw_transaction *t,
- struct fw_card *card)
+// card->transactions.lock should be acquired in advance for the linked list.
+static void start_split_transaction_timeout(struct fw_transaction *t, unsigned int delta)
{
- unsigned long delta;
-
if (list_empty(&t->link) || WARN_ON(t->is_split_transaction))
return;
t->is_split_transaction = true;
- // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
- // local destination never runs in any type of IRQ context.
- scoped_guard(spinlock_irqsave, &card->split_timeout.lock)
- delta = card->split_timeout.jiffies;
mod_timer(&t->split_timeout_timer, jiffies + delta);
}
@@ -207,13 +201,20 @@ static void transmit_complete_callback(struct fw_packet *packet,
break;
case ACK_PENDING:
{
+ unsigned int delta;
+
// NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
// local destination never runs in any type of IRQ context.
scoped_guard(spinlock_irqsave, &card->split_timeout.lock) {
t->split_timeout_cycle =
compute_split_timeout_timestamp(card, packet->timestamp) & 0xffff;
+ delta = card->split_timeout.jiffies;
}
- start_split_transaction_timeout(t, card);
+
+ // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
+ // local destination never runs in any type of IRQ context.
+ scoped_guard(spinlock_irqsave, &card->transactions.lock)
+ start_split_transaction_timeout(t, delta);
break;
}
case ACK_BUSY_X:
base-commit: 6b617317e5bc95e9962a712314ae0c4b7a4d5cc3
--
2.51.0
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-19 08:52:45
|
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 |
|
From: Takashi S. <o-t...@sa...> - 2026-01-17 14:28:52
|
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-t...@sa...>
---
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
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-17 14:28:51
|
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-t...@sa...>
---
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
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-17 14:28:45
|
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-t...@sa...>
---
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
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-17 14:28:45
|
Some cleanup helpers are useful in error path after memory allocation for
header storage.
Signed-off-by: Takashi Sakamoto <o-t...@sa...>
---
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
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-17 14:28:43
|
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-t...@sa...>
---
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
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-17 14:28:43
|
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-t...@sa...>
---
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
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-17 14:28:42
|
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-t...@sa...>
---
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
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-17 14:28:42
|
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-t...@sa...>
---
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
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-17 14:28:35
|
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
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-17 14:28:35
|
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-t...@sa...>
---
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
|
|
From: Takashi S. <o-t...@sa...> - 2026-01-15 13:38:06
|
Hi, On Thu, Jan 15, 2026 at 12:38:11PM +0000, AreYouLoco? via linux1394-devel wrote: > So kernel tree 6.19 is already going to contain that fix soon? > > Or for-next branch is some future release? The issued commit is only in for-next branch, which I maintain for next merge window. The issue is not included in Any release candidate of v6.19 kernel. Regards Takashi Sakamoto |