[alsa-devel] [PATCH 0/3] ALSA: oxfw: fixes for Stanton SCS.1d
Hi,
ALSA oxfw driver includes functionality of former snd-scs1x implements. However, since it was merged in Linux v4.5, the driver can't add sound card instance for Stanton SCS.1d due to its quirk.
This patchset fixes the regression.
Takashi Sakamoto (3): ALSA: oxfw: use ENXIO for not-supported cases ALSA: oxfw: don't add MIDI/PCM interface when packet streaming is unavailable ALSA: oxfw: fix for Stanton SCS.1d
sound/firewire/oxfw/oxfw-command.c | 6 +-- sound/firewire/oxfw/oxfw-stream.c | 82 +++++++++++++++++------------- sound/firewire/oxfw/oxfw.c | 39 +++++++------- sound/firewire/oxfw/oxfw.h | 1 + 4 files changed, 74 insertions(+), 54 deletions(-)
When AV/C command returns 'NOT IMPLEMENTED' status in its response, ALSA oxfw driver uses ENOSYS as error code. However, it's expected just to be used for missing system call number.
This commit replaces it with ENXIO.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/oxfw/oxfw-command.c | 6 +++--- sound/firewire/oxfw/oxfw-stream.c | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/sound/firewire/oxfw/oxfw-command.c b/sound/firewire/oxfw/oxfw-command.c index 16dc337c7093..d2e57c76070d 100644 --- a/sound/firewire/oxfw/oxfw-command.c +++ b/sound/firewire/oxfw/oxfw-command.c @@ -38,7 +38,7 @@ int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir, else if (err < len + 10) err = -EIO; else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ - err = -ENOSYS; + err = -ENXIO; else if (buf[0] == 0x0a) /* REJECTED */ err = -EINVAL; else @@ -83,7 +83,7 @@ int avc_stream_get_format(struct fw_unit *unit, else if (err < 12) err = -EIO; else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ - err = -ENOSYS; + err = -ENXIO; else if (buf[0] == 0x0a) /* REJECTED */ err = -EINVAL; else if (buf[0] == 0x0b) /* IN TRANSITION */ @@ -147,7 +147,7 @@ int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate, else if (err < 8) err = -EIO; else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ - err = -ENOSYS; + err = -ENXIO; if (err < 0) goto end;
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c index 501a80094bf7..692324670c78 100644 --- a/sound/firewire/oxfw/oxfw-stream.c +++ b/sound/firewire/oxfw/oxfw-stream.c @@ -513,7 +513,7 @@ int snd_oxfw_stream_parse_format(u8 *format, * Level 1: AM824 Compound (0x40) */ if ((format[0] != 0x90) || (format[1] != 0x40)) - return -ENOSYS; + return -ENXIO;
/* check the sampling rate */ for (i = 0; i < ARRAY_SIZE(avc_stream_rate_table); i++) { @@ -521,7 +521,7 @@ int snd_oxfw_stream_parse_format(u8 *format, break; } if (i == ARRAY_SIZE(avc_stream_rate_table)) - return -ENOSYS; + return -ENXIO;
formation->rate = oxfw_rate_table[i];
@@ -565,13 +565,13 @@ int snd_oxfw_stream_parse_format(u8 *format, /* Don't care */ case 0xff: default: - return -ENOSYS; /* not supported */ + return -ENXIO; /* not supported */ } }
if (formation->pcm > AM824_MAX_CHANNELS_FOR_PCM || formation->midi > AM824_MAX_CHANNELS_FOR_MIDI) - return -ENOSYS; + return -ENXIO;
return 0; } @@ -656,7 +656,7 @@ static int fill_stream_formats(struct snd_oxfw *oxfw, /* get first entry */ len = AVC_GENERIC_FRAME_MAXIMUM_BYTES; err = avc_stream_get_format_list(oxfw->unit, dir, 0, buf, &len, 0); - if (err == -ENOSYS) { + if (err == -ENXIO) { /* LIST subfunction is not implemented */ len = AVC_GENERIC_FRAME_MAXIMUM_BYTES; err = assume_stream_formats(oxfw, dir, pid, buf, &len, @@ -728,7 +728,7 @@ int snd_oxfw_stream_discover(struct snd_oxfw *oxfw) err); goto end; } else if ((plugs[0] == 0) && (plugs[1] == 0)) { - err = -ENOSYS; + err = -ENXIO; goto end; }
On Mon, 13 Jan 2020 08:34:16 +0100, Takashi Sakamoto wrote:
When AV/C command returns 'NOT IMPLEMENTED' status in its response, ALSA oxfw driver uses ENOSYS as error code. However, it's expected just to be used for missing system call number.
This commit replaces it with ENXIO.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp
Applied to for-next branch. Thanks.
Takashi
Stanton SCS.1d doesn't support packet streaming even if it has plugs for isochronous communication.
This commit is a preparation for this case. The 'has_input' member is added to specific structure, and MIDI/PCM interfaces are not added when the member is false.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/oxfw/oxfw-stream.c | 2 ++ sound/firewire/oxfw/oxfw.c | 39 +++++++++++++++++-------------- sound/firewire/oxfw/oxfw.h | 1 + 3 files changed, 25 insertions(+), 17 deletions(-)
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c index 692324670c78..36c3dd84d189 100644 --- a/sound/firewire/oxfw/oxfw-stream.c +++ b/sound/firewire/oxfw/oxfw-stream.c @@ -772,6 +772,8 @@ int snd_oxfw_stream_discover(struct snd_oxfw *oxfw) if (formation.midi > 0) oxfw->midi_output_ports = 1; } + + oxfw->has_input = true; } end: return err; diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c index fb6df3fc018e..1f1e3236efb8 100644 --- a/sound/firewire/oxfw/oxfw.c +++ b/sound/firewire/oxfw/oxfw.c @@ -118,7 +118,8 @@ static void oxfw_card_free(struct snd_card *card) { struct snd_oxfw *oxfw = card->private_data;
- snd_oxfw_stream_destroy_duplex(oxfw); + if (oxfw->has_output || oxfw->has_input) + snd_oxfw_stream_destroy_duplex(oxfw); }
static int detect_quirks(struct snd_oxfw *oxfw) @@ -206,23 +207,25 @@ static void do_registration(struct work_struct *work) if (err < 0) goto error;
- err = snd_oxfw_stream_init_duplex(oxfw); - if (err < 0) - goto error; + if (oxfw->has_output || oxfw->has_input) { + err = snd_oxfw_stream_init_duplex(oxfw); + if (err < 0) + goto error;
- err = snd_oxfw_create_pcm(oxfw); - if (err < 0) - goto error; + err = snd_oxfw_create_pcm(oxfw); + if (err < 0) + goto error;
- snd_oxfw_proc_init(oxfw); + snd_oxfw_proc_init(oxfw);
- err = snd_oxfw_create_midi(oxfw); - if (err < 0) - goto error; + err = snd_oxfw_create_midi(oxfw); + if (err < 0) + goto error;
- err = snd_oxfw_create_hwdep(oxfw); - if (err < 0) - goto error; + err = snd_oxfw_create_hwdep(oxfw); + if (err < 0) + goto error; + }
err = snd_card_register(oxfw->card); if (err < 0) @@ -274,9 +277,11 @@ static void oxfw_bus_reset(struct fw_unit *unit) fcp_bus_reset(oxfw->unit);
if (oxfw->registered) { - mutex_lock(&oxfw->mutex); - snd_oxfw_stream_update_duplex(oxfw); - mutex_unlock(&oxfw->mutex); + if (oxfw->has_output || oxfw->has_input) { + mutex_lock(&oxfw->mutex); + snd_oxfw_stream_update_duplex(oxfw); + mutex_unlock(&oxfw->mutex); + }
if (oxfw->entry->vendor_id == OUI_STANTON) snd_oxfw_scs1x_update(oxfw); diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h index c30e537087b0..fa2d7f9e2dc3 100644 --- a/sound/firewire/oxfw/oxfw.h +++ b/sound/firewire/oxfw/oxfw.h @@ -45,6 +45,7 @@ struct snd_oxfw {
bool wrong_dbs; bool has_output; + bool has_input; u8 *tx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES]; u8 *rx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES]; bool assumed;
On Mon, 13 Jan 2020 08:34:17 +0100, Takashi Sakamoto wrote:
Stanton SCS.1d doesn't support packet streaming even if it has plugs for isochronous communication.
This commit is a preparation for this case. The 'has_input' member is added to specific structure, and MIDI/PCM interfaces are not added when the member is false.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp
Applied to for-next branch. Thanks.
Takashi
Stanton SCS.1d uses Oxford Semiconductor FW 971 ASIC (FW971) for communication. Although the unit is bound to ALSA oxfw driver, the instance of sound card can not be added due to its quirk of plug information. This bug was added when snd-scs1x is merged into snd-oxfw at commit 9e2004f9cedf ("ALSA: oxfw: obsolete scs1x module").
This commit fixes the driver for the quirk. In cases that the unit returns NOT IMPLEMENTED for some AV/C commands, the sound card is added without any PCM/MIDI interfaces for packet streaming. For SCS.1d, model dependent operation adds MIDI interface and applications can use it to operate according to HSS1394 protocol from reverse-engineering work by Sean M. Pappalardo.
Plug Control Register (PCR) has information that the unit has a pair of plugs for isochronous communication:
(oMPR) $ ./firewire-request /dev/fw1 read 0xfffff0000900 result: 80ff0001 (iMPR) $ ./firewire-request /dev/fw1 read 0xfffff0000980 result: 80ff0001
AV/C PLUG INFO also returns information that the unit has a pair of plugs for isochronous communication.
(AV/C PLUG INFO command) $ ./firewire-request /dev/fw1 fcp 0x01ff0200ffffffff response: 000: 0c ff 02 00 01 01 02 02
However, AV/C PLUG SIGNAL INFO command is rejected for both plugs.
(AV/C OUTPUT PLUG SIGNAL INFO command) $ ./firewire-request /dev/fw1 fcp 0x01ff1800ffffffff response: 000: 0a ff 18 00 ff ff ff ff (AV/C INPUT PLUG SIGNAL INFO command) $ ./firewire-request /dev/fw1 fcp 0x01ff1900ffffffff response: 000: 0a ff 19 00 ff ff ff ff
Furthermore, AV/C EXTENDED STREAM FORMAT INFO is not implemented.
(AV/C EXTENDED STREAM FORMAT INFO list subfunction for input plug) $ ./firewire-request /dev/fw1 fcp 0x01ffbfc000000000ffff00ff response: 000: 08 ff bf c0 00 00 00 00 ff ff 00 ff (AV/C EXTENDED STREAM FORMAT INFO list subfunction for output plug) $ ./firewire-request /dev/fw1 fcp 0x01ffbfc001000000ffff00ff response: 000: 08 ff bf c0 01 00 00 00 ff ff 00 ff (AV/C EXTENDED STREAM FORMAT INFO single subfunction for input plug) $ ./firewire-request /dev/fw1 fcp 0x01ffbfc100000000ffffffff response: 000: 08 ff bf c1 00 00 00 00 ff ff ff ff (AV/C EXTENDED STREAM FORMAT INFO single subfunction for output plug) $ ./firewire-request /dev/fw1 fcp 0x01ffbfc101000000ffffffff response: 000: 08 ff bf c1 01 00 00 00 ff ff ff ff
Reference: https://mailman.alsa-project.org/pipermail/alsa-devel/2012-May/052264.html Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/oxfw/oxfw-stream.c | 72 ++++++++++++++++++------------- 1 file changed, 42 insertions(+), 30 deletions(-)
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c index 36c3dd84d189..80c9dc13f1b5 100644 --- a/sound/firewire/oxfw/oxfw-stream.c +++ b/sound/firewire/oxfw/oxfw-stream.c @@ -735,45 +735,57 @@ int snd_oxfw_stream_discover(struct snd_oxfw *oxfw) /* use oPCR[0] if exists */ if (plugs[1] > 0) { err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0); - if (err < 0) - goto end; + if (err < 0) { + if (err != -ENXIO) + return err;
- for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { - format = oxfw->tx_stream_formats[i]; - if (format == NULL) - continue; - err = snd_oxfw_stream_parse_format(format, &formation); - if (err < 0) - continue; - - /* Add one MIDI port. */ - if (formation.midi > 0) - oxfw->midi_input_ports = 1; - } + // The oPCR is not available for isoc communication. + err = 0; + } else { + for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { + format = oxfw->tx_stream_formats[i]; + if (format == NULL) + continue; + err = snd_oxfw_stream_parse_format(format, + &formation); + if (err < 0) + continue; + + /* Add one MIDI port. */ + if (formation.midi > 0) + oxfw->midi_input_ports = 1; + }
- oxfw->has_output = true; + oxfw->has_output = true; + } }
/* use iPCR[0] if exists */ if (plugs[0] > 0) { err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0); - if (err < 0) - goto end; + if (err < 0) { + if (err != -ENXIO) + return err;
- for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { - format = oxfw->rx_stream_formats[i]; - if (format == NULL) - continue; - err = snd_oxfw_stream_parse_format(format, &formation); - if (err < 0) - continue; - - /* Add one MIDI port. */ - if (formation.midi > 0) - oxfw->midi_output_ports = 1; - } + // The iPCR is not available for isoc communication. + err = 0; + } else { + for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { + format = oxfw->rx_stream_formats[i]; + if (format == NULL) + continue; + err = snd_oxfw_stream_parse_format(format, + &formation); + if (err < 0) + continue; + + /* Add one MIDI port. */ + if (formation.midi > 0) + oxfw->midi_output_ports = 1; + }
- oxfw->has_input = true; + oxfw->has_input = true; + } } end: return err;
On Mon, 13 Jan 2020 08:34:18 +0100, Takashi Sakamoto wrote:
Stanton SCS.1d uses Oxford Semiconductor FW 971 ASIC (FW971) for communication. Although the unit is bound to ALSA oxfw driver, the instance of sound card can not be added due to its quirk of plug information. This bug was added when snd-scs1x is merged into snd-oxfw at commit 9e2004f9cedf ("ALSA: oxfw: obsolete scs1x module").
This commit fixes the driver for the quirk. In cases that the unit returns NOT IMPLEMENTED for some AV/C commands, the sound card is added without any PCM/MIDI interfaces for packet streaming. For SCS.1d, model dependent operation adds MIDI interface and applications can use it to operate according to HSS1394 protocol from reverse-engineering work by Sean M. Pappalardo.
Plug Control Register (PCR) has information that the unit has a pair of plugs for isochronous communication:
(oMPR) $ ./firewire-request /dev/fw1 read 0xfffff0000900 result: 80ff0001 (iMPR) $ ./firewire-request /dev/fw1 read 0xfffff0000980 result: 80ff0001
AV/C PLUG INFO also returns information that the unit has a pair of plugs for isochronous communication.
(AV/C PLUG INFO command) $ ./firewire-request /dev/fw1 fcp 0x01ff0200ffffffff response: 000: 0c ff 02 00 01 01 02 02
However, AV/C PLUG SIGNAL INFO command is rejected for both plugs.
(AV/C OUTPUT PLUG SIGNAL INFO command) $ ./firewire-request /dev/fw1 fcp 0x01ff1800ffffffff response: 000: 0a ff 18 00 ff ff ff ff (AV/C INPUT PLUG SIGNAL INFO command) $ ./firewire-request /dev/fw1 fcp 0x01ff1900ffffffff response: 000: 0a ff 19 00 ff ff ff ff
Furthermore, AV/C EXTENDED STREAM FORMAT INFO is not implemented.
(AV/C EXTENDED STREAM FORMAT INFO list subfunction for input plug) $ ./firewire-request /dev/fw1 fcp 0x01ffbfc000000000ffff00ff response: 000: 08 ff bf c0 00 00 00 00 ff ff 00 ff (AV/C EXTENDED STREAM FORMAT INFO list subfunction for output plug) $ ./firewire-request /dev/fw1 fcp 0x01ffbfc001000000ffff00ff response: 000: 08 ff bf c0 01 00 00 00 ff ff 00 ff (AV/C EXTENDED STREAM FORMAT INFO single subfunction for input plug) $ ./firewire-request /dev/fw1 fcp 0x01ffbfc100000000ffffffff response: 000: 08 ff bf c1 00 00 00 00 ff ff ff ff (AV/C EXTENDED STREAM FORMAT INFO single subfunction for output plug) $ ./firewire-request /dev/fw1 fcp 0x01ffbfc101000000ffffffff response: 000: 08 ff bf c1 01 00 00 00 ff ff ff ff
Reference: https://mailman.alsa-project.org/pipermail/alsa-devel/2012-May/052264.html Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp
Applied to for-next branch. Thanks.
Takashi
participants (2)
-
Takashi Iwai
-
Takashi Sakamoto