git: c402d2e4b700 - main - fwisound: match unit directories instead of IDENTIFY
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 17 Jul 2026 04:09:29 UTC
The branch main has been updated by adrian:
URL: https://cgit.FreeBSD.org/src/commit/?id=c402d2e4b70023c633e6b3af5436de7033166d04
commit c402d2e4b70023c633e6b3af5436de7033166d04
Author: Abdelkader Boudih <freebsd@seuros.com>
AuthorDate: 2026-07-17 04:03:53 +0000
Commit: Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2026-07-17 04:07:52 +0000
fwisound: match unit directories instead of IDENTIFY
Migrated fwisound to use per-unit-directory child device
Differential Revision: https://reviews.freebsd.org/D58203
Reviewed by: adrian
---
share/man/man4/fwisound.4 | 5 +-
sys/dev/firewire/fwisound.c | 168 ++++++++++++++------------------------------
2 files changed, 54 insertions(+), 119 deletions(-)
diff --git a/share/man/man4/fwisound.4 b/share/man/man4/fwisound.4
index 0da89fbe2bdc..a458c957276e 100644
--- a/share/man/man4/fwisound.4
+++ b/share/man/man4/fwisound.4
@@ -3,7 +3,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.Dd June 19, 2026
+.Dd July 12, 2026
.Dt FWISOUND 4
.Os
.Sh NAME
@@ -20,7 +20,8 @@ driver provides audio capture from Apple FireWire devices that use a
proprietary isochronous audio protocol
.Pq not IEC 61883/AMDTP .
.Pp
-The driver matches FireWire units with Apple OUI
+The driver attaches to unit directories in the device CSR configuration ROM
+with Apple OUI
.Pq 0x000a27
and decodes the
.Qq sght
diff --git a/sys/dev/firewire/fwisound.c b/sys/dev/firewire/fwisound.c
index 9766f88060f7..63ebd5f01917 100644
--- a/sys/dev/firewire/fwisound.c
+++ b/sys/dev/firewire/fwisound.c
@@ -46,12 +46,9 @@ SYSCTL_INT(_hw_firewire_fwisound, OID_AUTO, iso_channel, CTLFLAG_RWTUN,
printf("fwisound: " fmt, ## __VA_ARGS__); \
} while (0)
-static void fwisound_identify(driver_t *, device_t);
static int fwisound_probe(device_t);
static int fwisound_attach(device_t);
static int fwisound_detach(device_t);
-static void fwisound_post_busreset(void *);
-static void fwisound_post_explore(void *);
static void fwisound_probe_task(void *, int);
static void fwisound_start_task(void *, int);
static void fwisound_stop_task(void *, int);
@@ -105,49 +102,35 @@ fwisound_write_quadlet(struct fwisound_softc *sc, uint32_t offset, uint32_t val)
return (err);
}
+/*
+ * Extract the audio command base register (key 0x40) from the unit directory.
+ */
static uint32_t
-fwisound_find_audio_unit(struct fw_device *fwdev)
+fwisound_find_audio_base(struct fw_unit *unit)
{
- struct csrhdr *hdr;
- struct csrdirectory *root, *udir;
- struct csrreg *reg, *u;
- int i, j, spec_ok, ver_ok;
- uint32_t audio_base;
-
- hdr = (struct csrhdr *)fwdev->csrrom;
- if (hdr->info_len <= 1)
+ struct fw_device *fwdev = unit->fwdev;
+ struct csrdirectory *udir;
+ struct csrreg *reg;
+ uint32_t udir_qoff, udir_len, rom_quads;
+ int i;
+
+ rom_quads = CSRROMSIZE / 4;
+ udir_qoff = unit->dir_offset / 4;
+ if (udir_qoff >= rom_quads)
return (0);
- root = (struct csrdirectory *)(fwdev->csrrom + 1 + hdr->info_len);
-
- for (i = 0; i < root->crc_len; i++) {
- reg = &root->entry[i];
-
- if (reg->key != CROM_UDIR)
- continue;
-
- udir = (struct csrdirectory *)(reg + reg->val);
-
- spec_ok = 0;
- ver_ok = 0;
- audio_base = 0;
-
- for (j = 0; j < udir->crc_len; j++) {
- u = &udir->entry[j];
-
- if (u->key == CSRKEY_SPEC && u->val == FWISOUND_SPEC_ID)
- spec_ok = 1;
- else if (u->key == CSRKEY_VER &&
- u->val == FWISOUND_VERSION)
- ver_ok = 1;
- else if (u->key == IIDC_CROM_CMD_BASE)
- audio_base = u->val;
- }
+ udir = (struct csrdirectory *)&fwdev->csrrom[udir_qoff];
+ udir_len = udir->crc_len;
+ if (udir_qoff + 1 + udir_len > rom_quads)
+ return (0);
- if (spec_ok && ver_ok && audio_base != 0)
- return (audio_base);
+ for (i = 0; i < (int)udir_len; i++) {
+ if (udir_qoff + 1 + i >= rom_quads)
+ break;
+ reg = &udir->entry[i];
+ if (reg->key == IIDC_CROM_CMD_BASE && reg->val != 0)
+ return (reg->val);
}
-
return (0);
}
@@ -445,96 +428,50 @@ fwisound_iso_input(struct fw_xferq *xferq)
&sc->dma_ch, dma_ch);
}
-static void
-fwisound_post_explore(void *arg)
-{
- struct fwisound_softc *sc = (struct fwisound_softc *)arg;
- struct fw_device *fwdev;
- uint32_t audio_base;
- int err;
-
- FWISOUND_LOCK(sc);
- if (sc->state == FWISOUND_STATE_DETACHING) {
- FWISOUND_UNLOCK(sc);
- return;
- }
-
- if (sc->fwdev != NULL) {
- STAILQ_FOREACH(fwdev, &sc->fd.fc->devices, link) {
- if (fwdev == sc->fwdev &&
- fwdev->status == FWDEVATTACHED)
- break;
- }
- if (fwdev == NULL) {
- device_printf(sc->dev, "device disconnected\n");
- sc->fwdev = NULL;
- sc->state = FWISOUND_STATE_IDLE;
- FWISOUND_UNLOCK(sc);
- fwisound_iso_stop(sc);
- FWISOUND_LOCK(sc);
- }
- }
-
- if (sc->fwdev == NULL) {
- STAILQ_FOREACH(fwdev, &sc->fd.fc->devices, link) {
- if (fwdev->status != FWDEVATTACHED)
- continue;
-
- audio_base = fwisound_find_audio_unit(fwdev);
- if (audio_base == 0)
- continue;
-
- sc->fwdev = fwdev;
- sc->cmd_hi = 0xffff;
- sc->cmd_lo = 0xf0000000 | (audio_base << 2);
-
- FWISOUND_UNLOCK(sc);
- err = taskqueue_enqueue(taskqueue_thread,
- &sc->probe_task);
- if (err != 0)
- device_printf(sc->dev,
- "taskqueue_enqueue failed: %d\n", err);
- return;
- }
- }
-
- FWISOUND_UNLOCK(sc);
-}
-
-static void
-fwisound_post_busreset(void *arg __unused)
-{
-
-}
-
-static void
-fwisound_identify(driver_t *driver, device_t parent)
-{
-
- if (device_find_child(parent, "fwisound", DEVICE_UNIT_ANY) == NULL)
- BUS_ADD_CHILD(parent, 0, "fwisound", DEVICE_UNIT_ANY);
-}
static int
fwisound_probe(device_t dev)
{
+ struct fw_unit *unit;
+
+ unit = fw_get_unit(dev);
+ if (unit == NULL)
+ return (ENXIO);
+
+ if (unit->spec_id != FWISOUND_SPEC_ID ||
+ unit->sw_version != FWISOUND_VERSION)
+ return (ENXIO);
device_set_desc(dev, "Apple FireWire Audio");
- return (0);
+ return (BUS_PROBE_DEFAULT);
}
static int
fwisound_attach(device_t dev)
{
struct fwisound_softc *sc;
+ struct fw_unit *unit;
+ uint32_t audio_base;
+
+ unit = fw_get_unit(dev);
+ if (unit == NULL || unit->fwdev == NULL)
+ return (ENXIO);
+
+ audio_base = fwisound_find_audio_base(unit);
+ if (audio_base == 0) {
+ device_printf(dev, "no audio base in unit directory\n");
+ return (ENXIO);
+ }
sc = device_get_softc(dev);
sc->fd.dev = dev;
- sc->fd.fc = device_get_ivars(dev);
+ sc->fd.fc = fw_get_comm(dev);
sc->dev = dev;
mtx_init(&sc->mtx, "fwisound", NULL, MTX_DEF);
- sc->fwdev = NULL;
+ sc->fwdev = unit->fwdev;
+ sc->cmd_hi = 0xffff;
+ sc->cmd_lo = 0xf0000000 | (audio_base << 2);
sc->state = FWISOUND_STATE_IDLE;
sc->dma_ch = -1;
sc->iso_active = 0;
@@ -544,9 +481,6 @@ fwisound_attach(device_t dev)
TASK_INIT(&sc->start_task, 0, fwisound_start_task, sc);
TASK_INIT(&sc->stop_task, 0, fwisound_stop_task, sc);
- sc->fd.post_busreset = fwisound_post_busreset;
- sc->fd.post_explore = fwisound_post_explore;
-
sc->pcm_dev = device_add_child(dev, "pcm", DEVICE_UNIT_ANY);
if (sc->pcm_dev == NULL) {
device_printf(dev, "failed to add pcm child\n");
@@ -556,7 +490,8 @@ fwisound_attach(device_t dev)
bus_attach_children(dev);
- fwisound_post_explore(sc);
+ if (taskqueue_enqueue(taskqueue_thread, &sc->probe_task) != 0)
+ device_printf(dev, "failed to enqueue probe task\n");
return (0);
}
@@ -589,7 +524,6 @@ fwisound_detach(device_t dev)
}
static device_method_t fwisound_methods[] = {
- DEVMETHOD(device_identify, fwisound_identify),
DEVMETHOD(device_probe, fwisound_probe),
DEVMETHOD(device_attach, fwisound_attach),
DEVMETHOD(device_detach, fwisound_detach),