Skip to content

Commit 4f380d0

Browse files
takaswietiwai
authored andcommitted
ALSA: oxfw: configure packet format in pcm.hw_params callback
This commit is a part of preparation to perform allocation/release of isochronous resources in pcm.hw_params/hw_free callbacks. At present, several operations are done in pcm.prepare callback. To reduce load of the callback, This commit splits out an operation to set packet format in pcm.hw_params callback. Signed-off-by: Takashi Sakamoto <[email protected]> Signed-off-by: Takashi Iwai <[email protected]>
1 parent 4a0a047 commit 4f380d0

File tree

4 files changed

+62
-29
lines changed

4 files changed

+62
-29
lines changed

sound/firewire/oxfw/oxfw-midi.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ static int midi_capture_open(struct snd_rawmidi_substream *substream)
1919

2020
mutex_lock(&oxfw->mutex);
2121

22-
++oxfw->substreams_count;
23-
err = snd_oxfw_stream_start_duplex(oxfw, &oxfw->tx_stream, 0, 0);
22+
err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream, 0, 0);
23+
if (err >= 0) {
24+
++oxfw->substreams_count;
25+
err = snd_oxfw_stream_start_duplex(oxfw);
26+
}
2427

2528
mutex_unlock(&oxfw->mutex);
2629

@@ -41,8 +44,11 @@ static int midi_playback_open(struct snd_rawmidi_substream *substream)
4144

4245
mutex_lock(&oxfw->mutex);
4346

44-
++oxfw->substreams_count;
45-
err = snd_oxfw_stream_start_duplex(oxfw, &oxfw->rx_stream, 0, 0);
47+
err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream, 0, 0);
48+
if (err >= 0) {
49+
++oxfw->substreams_count;
50+
err = snd_oxfw_stream_start_duplex(oxfw);
51+
}
4652

4753
mutex_unlock(&oxfw->mutex);
4854

sound/firewire/oxfw/oxfw-pcm.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,18 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
219219
return err;
220220

221221
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
222+
unsigned int rate = params_rate(hw_params);
223+
unsigned int channels = params_channels(hw_params);
224+
222225
mutex_lock(&oxfw->mutex);
223-
++oxfw->substreams_count;
226+
err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream,
227+
rate, channels);
228+
if (err >= 0)
229+
++oxfw->substreams_count;
224230
mutex_unlock(&oxfw->mutex);
225231
}
226232

227-
return 0;
233+
return err;
228234
}
229235
static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
230236
struct snd_pcm_hw_params *hw_params)
@@ -238,8 +244,14 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
238244
return err;
239245

240246
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
247+
unsigned int rate = params_rate(hw_params);
248+
unsigned int channels = params_channels(hw_params);
249+
241250
mutex_lock(&oxfw->mutex);
242-
++oxfw->substreams_count;
251+
err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream,
252+
rate, channels);
253+
if (err >= 0)
254+
++oxfw->substreams_count;
243255
mutex_unlock(&oxfw->mutex);
244256
}
245257

@@ -280,12 +292,10 @@ static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
280292
static int pcm_capture_prepare(struct snd_pcm_substream *substream)
281293
{
282294
struct snd_oxfw *oxfw = substream->private_data;
283-
struct snd_pcm_runtime *runtime = substream->runtime;
284295
int err;
285296

286297
mutex_lock(&oxfw->mutex);
287-
err = snd_oxfw_stream_start_duplex(oxfw, &oxfw->tx_stream,
288-
runtime->rate, runtime->channels);
298+
err = snd_oxfw_stream_start_duplex(oxfw);
289299
mutex_unlock(&oxfw->mutex);
290300
if (err < 0)
291301
goto end;
@@ -297,12 +307,10 @@ static int pcm_capture_prepare(struct snd_pcm_substream *substream)
297307
static int pcm_playback_prepare(struct snd_pcm_substream *substream)
298308
{
299309
struct snd_oxfw *oxfw = substream->private_data;
300-
struct snd_pcm_runtime *runtime = substream->runtime;
301310
int err;
302311

303312
mutex_lock(&oxfw->mutex);
304-
err = snd_oxfw_stream_start_duplex(oxfw, &oxfw->rx_stream,
305-
runtime->rate, runtime->channels);
313+
err = snd_oxfw_stream_start_duplex(oxfw);
306314
mutex_unlock(&oxfw->mutex);
307315
if (err < 0)
308316
goto end;

sound/firewire/oxfw/oxfw-stream.c

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -236,16 +236,13 @@ static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
236236
return 0;
237237
}
238238

239-
int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw,
240-
struct amdtp_stream *stream,
241-
unsigned int rate, unsigned int pcm_channels)
239+
int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
240+
struct amdtp_stream *stream,
241+
unsigned int rate, unsigned int pcm_channels)
242242
{
243243
struct snd_oxfw_stream_formation formation;
244244
enum avc_general_plug_dir dir;
245-
int err = 0;
246-
247-
if (oxfw->substreams_count == 0)
248-
return -EIO;
245+
int err;
249246

250247
// Considering JACK/FFADO streaming:
251248
// TODO: This can be removed hwdep functionality becomes popular.
@@ -266,22 +263,22 @@ int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw,
266263
err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
267264
if (err < 0)
268265
return err;
269-
if (rate == 0)
266+
if (rate == 0) {
270267
rate = formation.rate;
271-
if (pcm_channels == 0)
272268
pcm_channels = formation.pcm;
273-
274-
if (formation.rate != rate || formation.pcm != pcm_channels ||
275-
amdtp_streaming_error(&oxfw->rx_stream) ||
276-
amdtp_streaming_error(&oxfw->tx_stream)) {
269+
}
270+
if (formation.rate != rate || formation.pcm != pcm_channels) {
277271
amdtp_stream_stop(&oxfw->rx_stream);
278272
cmp_connection_break(&oxfw->in_conn);
279273

280274
if (oxfw->has_output) {
281275
amdtp_stream_stop(&oxfw->tx_stream);
282276
cmp_connection_break(&oxfw->out_conn);
283277
}
278+
}
284279

280+
if (oxfw->substreams_count == 0 ||
281+
formation.rate != rate || formation.pcm != pcm_channels) {
285282
err = set_stream_format(oxfw, stream, rate, pcm_channels);
286283
if (err < 0) {
287284
dev_err(&oxfw->unit->device,
@@ -290,6 +287,27 @@ int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw,
290287
}
291288
}
292289

290+
return 0;
291+
}
292+
293+
int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
294+
{
295+
int err;
296+
297+
if (oxfw->substreams_count == 0)
298+
return -EIO;
299+
300+
if (amdtp_streaming_error(&oxfw->rx_stream) ||
301+
amdtp_streaming_error(&oxfw->tx_stream)) {
302+
amdtp_stream_stop(&oxfw->rx_stream);
303+
cmp_connection_break(&oxfw->in_conn);
304+
305+
if (oxfw->has_output) {
306+
amdtp_stream_stop(&oxfw->tx_stream);
307+
cmp_connection_break(&oxfw->out_conn);
308+
}
309+
}
310+
293311
if (!amdtp_stream_running(&oxfw->rx_stream)) {
294312
err = start_stream(oxfw, &oxfw->rx_stream);
295313
if (err < 0) {

sound/firewire/oxfw/oxfw.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,10 @@ int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate,
9999
unsigned short pid);
100100

101101
int snd_oxfw_stream_init_duplex(struct snd_oxfw *oxfw);
102-
int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw,
103-
struct amdtp_stream *stream,
104-
unsigned int rate, unsigned int pcm_channels);
102+
int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
103+
struct amdtp_stream *stream,
104+
unsigned int rate, unsigned int pcm_channels);
105+
int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw);
105106
void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw);
106107
void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw);
107108
void snd_oxfw_stream_update_duplex(struct snd_oxfw *oxfw);

0 commit comments

Comments
 (0)