summaryrefslogtreecommitdiffstats
path: root/sound/firewire/oxfw
diff options
context:
space:
mode:
Diffstat (limited to 'sound/firewire/oxfw')
-rw-r--r--sound/firewire/oxfw/oxfw-command.c6
-rw-r--r--sound/firewire/oxfw/oxfw-pcm.c21
-rw-r--r--sound/firewire/oxfw/oxfw-stream.c82
-rw-r--r--sound/firewire/oxfw/oxfw.c39
-rw-r--r--sound/firewire/oxfw/oxfw.h1
5 files changed, 79 insertions, 70 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-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c
index 67fd3e844dd6..2dfa7e179cb6 100644
--- a/sound/firewire/oxfw/oxfw-pcm.c
+++ b/sound/firewire/oxfw/oxfw-pcm.c
@@ -237,11 +237,7 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct snd_oxfw *oxfw = substream->private_data;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
+ int err = 0;
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
unsigned int rate = params_rate(hw_params);
@@ -264,11 +260,7 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct snd_oxfw *oxfw = substream->private_data;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
+ int err = 0;
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
unsigned int rate = params_rate(hw_params);
@@ -301,7 +293,7 @@ static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
mutex_unlock(&oxfw->mutex);
- return snd_pcm_lib_free_pages(substream);
+ return 0;
}
static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
{
@@ -316,7 +308,7 @@ static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
mutex_unlock(&oxfw->mutex);
- return snd_pcm_lib_free_pages(substream);
+ return 0;
}
static int pcm_capture_prepare(struct snd_pcm_substream *substream)
@@ -419,7 +411,6 @@ int snd_oxfw_create_pcm(struct snd_oxfw *oxfw)
static const struct snd_pcm_ops capture_ops = {
.open = pcm_open,
.close = pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
.hw_params = pcm_capture_hw_params,
.hw_free = pcm_capture_hw_free,
.prepare = pcm_capture_prepare,
@@ -430,7 +421,6 @@ int snd_oxfw_create_pcm(struct snd_oxfw *oxfw)
static const struct snd_pcm_ops playback_ops = {
.open = pcm_open,
.close = pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
.hw_params = pcm_playback_hw_params,
.hw_free = pcm_playback_hw_free,
.prepare = pcm_playback_prepare,
@@ -454,8 +444,7 @@ int snd_oxfw_create_pcm(struct snd_oxfw *oxfw)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
if (cap > 0)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_VMALLOC,
- NULL, 0, 0);
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
return 0;
}
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c
index 501a80094bf7..80c9dc13f1b5 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,49 +728,63 @@ 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;
}
/* 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;
+
+ // 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;
+ }
- 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;
}
}
end:
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;