Posts
114
Following
28
Followers
26
A maintainer of Linux FireWire subsystem and ALSA firewire stack.
http://ieee1394.docs.kernel.org/
https://github.com/takaswie/linux-firewire-dkms/

Takashi Sakamoto (坂本 貴史)

Edited 1 month ago
The pair of client_get() and queue_delayed_work() is called in queue_bus_reset_event() just for iso_resource_auto, so it is a simple solution to split iso_resource_once, then take care of the workqueue cancellation.
0
0
0

Takashi Sakamoto (坂本 貴史)

Edited 1 month ago
static void iso_resource_auto_work(struct work_struct *work)
{
        struct iso_resource_auto *r = from_work(r, work, work.work);
        struct client *client = r->client;
        unsigned long index = r->resource.handle;
        u64 reset_jiffies;
        struct iso_resource_event *e;
        int resource_generation, current_generation;
        int channel, bandwidth, todo;
        bool free = false;

        scoped_guard(spinlock_irq, &client->device->card->lock) {
                reset_jiffies = client->device->card->reset_jiffies;
                current_generation = client->device->generation;
        }

        scoped_guard(spinlock_irq, &client->lock) {
                resource_generation = r->generation;
                r->generation = current_generation;
                todo = r->todo;
        }

        switch (todo) {
        case ISO_RES_AUTO_ALLOC:
                // Allow 1000ms grace period for other reallocations.
                if (time_is_after_jiffies64(reset_jiffies + secs_to_jiffies(1))) {
                        scoped_guard(spinlock_irq, &client->lock)
                                schedule_iso_resource_auto(r, msecs_to_jiffies(333));
                        goto out;
                }
                break;
        case ISO_RES_AUTO_REALLOC:
                // We could be called twice within the same generation.
                if (resource_generation == current_generation)
                        goto out;
                break;
        case ISO_RES_AUTO_DEALLOC:
        default:
                break;
        }

        bandwidth = r->bandwidth;

        fw_iso_resource_manage(client->device->card, current_generation,
                        r->channels, &channel, &bandwidth,
                        todo == ISO_RES_AUTO_ALLOC ||
                        todo == ISO_RES_AUTO_REALLOC);

        if (todo == ISO_RES_AUTO_DEALLOC) {
                e = no_free_ptr(r->e_dealloc);
        } else {
                // Is this generation outdated already?  As long as this resource sticks in the
                // xarray, it will be scheduled again for a newer generation or at shutdown.
                if (channel == -EAGAIN)
                        goto out;

                // Finishes successfully.
                if (channel >= 0 || bandwidth > 0) {
                        // Generate no event at reallocation.
                        if (todo == ISO_RES_AUTO_REALLOC)
                                goto out;

                        scoped_guard(spinlock_irq, &client->lock) {
                                // Transit from allocation to reallocation, except if the client
                                // requested deallocation in the meantime.
                                r->todo = ISO_RES_AUTO_REALLOC;
                                r->channels = 1ULL << channel;
                        }
                } else {
                        // Allocation or reallocation failure?  Pull this resource out of the
                        // xarray and prepare for deletion, unless the client is shutting down.
                        scoped_guard(spinlock_irq, &client->lock) {
                                if (!client->in_shutdown && xa_erase(&client->resource_xa, index)) {
                                        client_put(client);
                                        free = true;
                                }
                        }
                }

                e = no_free_ptr(r->e_alloc);
        }

        e->iso_resource.handle    = r->resource.handle;
        e->iso_resource.channel   = channel;
        e->iso_resource.bandwidth = bandwidth;

        queue_event(client, &e->event,
                    &e->iso_resource, sizeof(e->iso_resource), NULL, 0);

        if (free) {
                cancel_delayed_work(&r->work);
                kfree(r->e_alloc);
                kfree(r->e_dealloc);
                kfree(r);
        }
 out:
        client_put(client);
}

static void iso_resource_once_work(struct work_struct *work)
{
        struct iso_resource_once *r = from_work(r, work, work.work);
        struct client *client = r->client;
        struct iso_resource_event *e;
        int generation, channel, bandwidth;

        generation = client->device->generation;

        bandwidth = r->bandwidth;
        r->generation = generation;

        fw_iso_resource_manage(client->device->card, generation, r->channels, &channel, &bandwidth,
                               r->todo == ISO_RES_ONCE_ALLOC);

        e = no_free_ptr(r->event);
        e->iso_resource.channel   = channel;
        e->iso_resource.bandwidth = bandwidth;

        queue_event(client, &e->event, &e->iso_resource, sizeof(e->iso_resource), NULL, 0);

        cancel_delayed_work(&r->work);
        client_put(r->client);
        kfree(r);
}
0
0
0

Takashi Sakamoto (坂本 貴史)

Oops, being uninitialized...

Re: firewire-ohci: 7.0.0-rc1 warnings+crash
https://lore.kernel.org/lkml/20260228031255.GA832746@workstation.local/
1
0
0

Takashi Sakamoto (坂本 貴史)

0
0
0

Takashi Sakamoto (坂本 貴史)

Re: Bug#1126090: Firewire-ohci module crashes: firewire_ohci 0000:02:00.0: failed to read phy reg 2
https://lore.kernel.org/lkml/20260205123722.GA303762@workstation.local/

Being messed up...
0
0
0

Takashi Sakamoto (坂本 貴史)

I sent:
[GIT PULL] firewire fixes for v6.19-rc8:
https://lore.kernel.org/lkml/20260130225427.GA88593@workstation.local/T/#u

firewire fixes for 6.19-rc8

Fix a race condition introduced in v6.18. Andreas Persson discovered this
issue while working with Focusrite Saffire Pro 40 (TCD33070). The fw_card
instance maintains a linked list of pending transactions, which must be
protected against concurrent access. However, a commit b5725cfa4120
("firewire: core: use spin lock specific to timer for split transaction")
unintentionally allowed concurrent accesses to this list. Fix this by
adjusting the relevant critical sections to properly serialize access.
0
0
0

Takashi Sakamoto (坂本 貴史)

I made an apparent regression, sigh...

[PATCH] firewire: core: fix race condition against transaction list
https://lore.kernel.org/lkml/20260127223413.22265-1-o-takashi@sakamocchi.jp/
0
0
0

Takashi Sakamoto (坂本 貴史)

I posted:

0
0
0

Takashi Sakamoto (坂本 貴史)

Hm:

An end to high memory?
https://lwn.net/Articles/813201/
0
0
0

Takashi Sakamoto (坂本 貴史)

0
0
0

Takashi Sakamoto (坂本 貴史)

I just tried, for now:
[PATCH] scatterlist: remove ambiguous comment for public fields count of mapping iterator
https://lore.kernel.org/lkml/20251214032533.702368-1-o-takashi@sakamocchi.jp/T/#u
0
0
0

Takashi Sakamoto (坂本 貴史)

0
0
0

Takashi Sakamoto (坂本 貴史)

A new user appeared for a pair of dma_alloc_pages() and dma_free_pages()...

[PATCH v12 6/9] tee: add tee_shm_alloc_dma_mem()
https://lore.kernel.org/op-tee/20250911135007.1275833-7-jens.wiklander@linaro.org/
0
0
0

Takashi Sakamoto (坂本 貴史)

I'm trying using the following utilities to eliminate the usage of page_private() from 1394 OHCI and core:

* struct scatterlist
* struct sg_table
* dma_alloc_noncontiguous()
* dma_vmap_noncontiguous()
* dma_mmap_noncontiguous()

I've never tested yet the integration.
0
0
0

Takashi Sakamoto (坂本 貴史)

when we can assume either PartialEq or Eq.
0
0
0

Takashi Sakamoto (坂本 貴史)

ptr_0 == ptr_1

equals to

ptr_0->node_id == ptr_1->node_id &&
ptr_0->tlabel == ptr_1->tlabel

but

ptr_0->node_id == ptr_1->node_id &&
ptr_0->tlabel == ptr_1->tlabel

does not equals to

ptr_0 == ptr_1
0
0
0

Takashi Sakamoto (坂本 貴史)

Edited 7 months ago
acknowledge code = 0x10 to any type of transaction is out of specification. MOTU Audio Express.
0
0
0
Show older