Skip to content

Commit

Permalink
ALSA: firewire-lib: process payload of isoc context according to pack…
Browse files Browse the repository at this point in the history
…et descriptors

This commit changes each of data block processing layer so that it
receives list of packet descriptor.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Sakamoto authored and Takashi Iwai committed Jul 22, 2019
1 parent 4731c67 commit 9a738ad
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 148 deletions.
71 changes: 42 additions & 29 deletions sound/firewire/amdtp-am824.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,45 +345,59 @@ static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
}
}

static unsigned int process_rx_data_blocks(struct amdtp_stream *s,
const struct pkt_desc *desc,
struct snd_pcm_substream *pcm)
static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
const struct pkt_desc *descs,
unsigned int packets,
struct snd_pcm_substream *pcm)
{
struct amdtp_am824 *p = s->protocol;
unsigned int pcm_frames = 0;
int i;

if (pcm) {
write_pcm_s32(s, pcm, desc->ctx_payload, desc->data_blocks,
pcm_frames);
pcm_frames = desc->data_blocks * p->frame_multiplier;
} else {
write_pcm_silence(s, desc->ctx_payload, desc->data_blocks);
}
for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = descs + i;
__be32 *buf = desc->ctx_payload;
unsigned int data_blocks = desc->data_blocks;

if (p->midi_ports) {
write_midi_messages(s, desc->ctx_payload, desc->data_blocks,
desc->data_block_counter);
if (pcm) {
write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
pcm_frames += data_blocks * p->frame_multiplier;
} else {
write_pcm_silence(s, buf, data_blocks);
}

if (p->midi_ports) {
write_midi_messages(s, buf, data_blocks,
desc->data_block_counter);
}
}

return pcm_frames;
}

static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
const struct pkt_desc *desc,
struct snd_pcm_substream *pcm)
static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
const struct pkt_desc *descs,
unsigned int packets,
struct snd_pcm_substream *pcm)
{
struct amdtp_am824 *p = s->protocol;
unsigned int pcm_frames = 0;
int i;

if (pcm) {
read_pcm_s32(s, pcm, desc->ctx_payload, desc->data_blocks,
pcm_frames);
pcm_frames = desc->data_blocks * p->frame_multiplier;
}
for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = descs + i;
__be32 *buf = desc->ctx_payload;
unsigned int data_blocks = desc->data_blocks;

if (pcm) {
read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
pcm_frames += data_blocks * p->frame_multiplier;
}

if (p->midi_ports) {
read_midi_messages(s, desc->ctx_payload, desc->data_blocks,
desc->data_block_counter);
if (p->midi_ports) {
read_midi_messages(s, buf, data_blocks,
desc->data_block_counter);
}
}

return pcm_frames;
Expand All @@ -400,15 +414,14 @@ static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir, enum cip_flags flags)
{
amdtp_stream_process_data_blocks_t process_data_blocks;
amdtp_stream_process_ctx_payloads_t process_ctx_payloads;

if (dir == AMDTP_IN_STREAM)
process_data_blocks = process_tx_data_blocks;
process_ctx_payloads = process_ir_ctx_payloads;
else
process_data_blocks = process_rx_data_blocks;
process_ctx_payloads = process_it_ctx_payloads;

return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
process_data_blocks,
sizeof(struct amdtp_am824));
process_ctx_payloads, sizeof(struct amdtp_am824));
}
EXPORT_SYMBOL_GPL(amdtp_am824_init);
25 changes: 10 additions & 15 deletions sound/firewire/amdtp-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,16 @@ static void pcm_period_tasklet(unsigned long data);
* @dir: the direction of stream
* @flags: the packet transmission method to use
* @fmt: the value of fmt field in CIP header
* @process_data_blocks: callback handler to process data blocks
* @process_ctx_payloads: callback handler to process payloads of isoc context
* @protocol_size: the size to allocate newly for protocol
*/
int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir, enum cip_flags flags,
unsigned int fmt,
amdtp_stream_process_data_blocks_t process_data_blocks,
amdtp_stream_process_ctx_payloads_t process_ctx_payloads,
unsigned int protocol_size)
{
if (process_data_blocks == NULL)
if (process_ctx_payloads == NULL)
return -EINVAL;

s->protocol = kzalloc(protocol_size, GFP_KERNEL);
Expand All @@ -102,7 +102,7 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
s->callbacked = false;

s->fmt = fmt;
s->process_data_blocks = process_data_blocks;
s->process_ctx_payloads = process_ctx_payloads;

if (dir == AMDTP_OUT_STREAM)
s->ctx_data.rx.syt_override = -1;
Expand Down Expand Up @@ -764,18 +764,13 @@ static void process_ctx_payloads(struct amdtp_stream *s,
const struct pkt_desc *descs,
unsigned int packets)
{
int i;

for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = descs + i;
struct snd_pcm_substream *pcm = READ_ONCE(s->pcm);
unsigned int pcm_frames;

pcm_frames = s->process_data_blocks(s, desc, pcm);
struct snd_pcm_substream *pcm;
unsigned int pcm_frames;

if (pcm && pcm_frames > 0)
update_pcm_pointers(s, pcm, pcm_frames);
}
pcm = READ_ONCE(s->pcm);
pcm_frames = s->process_ctx_payloads(s, descs, packets, pcm);
if (pcm)
update_pcm_pointers(s, pcm, pcm_frames);
}

static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
Expand Down
7 changes: 4 additions & 3 deletions sound/firewire/amdtp-stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ struct pkt_desc {
};

struct amdtp_stream;
typedef unsigned int (*amdtp_stream_process_data_blocks_t)(
typedef unsigned int (*amdtp_stream_process_ctx_payloads_t)(
struct amdtp_stream *s,
const struct pkt_desc *desc,
unsigned int packets,
struct snd_pcm_substream *pcm);
struct amdtp_stream {
struct fw_unit *unit;
Expand Down Expand Up @@ -168,13 +169,13 @@ struct amdtp_stream {

/* For backends to process data blocks. */
void *protocol;
amdtp_stream_process_data_blocks_t process_data_blocks;
amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
};

int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir, enum cip_flags flags,
unsigned int fmt,
amdtp_stream_process_data_blocks_t process_data_blocks,
amdtp_stream_process_ctx_payloads_t process_ctx_payloads,
unsigned int protocol_size);
void amdtp_stream_destroy(struct amdtp_stream *s);

Expand Down
66 changes: 40 additions & 26 deletions sound/firewire/digi00x/amdtp-dot.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,60 +341,74 @@ void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port,
WRITE_ONCE(p->midi[port], midi);
}

static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
const struct pkt_desc *desc,
struct snd_pcm_substream *pcm)
static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
const struct pkt_desc *descs,
unsigned int packets,
struct snd_pcm_substream *pcm)
{
unsigned int pcm_frames = 0;
int i;

if (pcm) {
read_pcm_s32(s, pcm, desc->ctx_payload, desc->data_blocks,
pcm_frames);
pcm_frames = desc->data_blocks;
}
for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = descs + i;
__be32 *buf = desc->ctx_payload;
unsigned int data_blocks = desc->data_blocks;

read_midi_messages(s, desc->ctx_payload, desc->data_blocks);
if (pcm) {
read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
pcm_frames += data_blocks;
}

read_midi_messages(s, buf, data_blocks);
}

return pcm_frames;
}

static unsigned int process_rx_data_blocks(struct amdtp_stream *s,
const struct pkt_desc *desc,
struct snd_pcm_substream *pcm)
static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
const struct pkt_desc *descs,
unsigned int packets,
struct snd_pcm_substream *pcm)
{
unsigned int pcm_frames = 0;
int i;

if (pcm) {
write_pcm_s32(s, pcm, desc->ctx_payload, desc->data_blocks,
pcm_frames);
pcm_frames = desc->data_blocks;
} else {
write_pcm_silence(s, desc->ctx_payload, desc->data_blocks);
}
for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = descs + i;
__be32 *buf = desc->ctx_payload;
unsigned int data_blocks = desc->data_blocks;

write_midi_messages(s, desc->ctx_payload, desc->data_blocks,
desc->data_block_counter);
if (pcm) {
write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
pcm_frames += data_blocks;
} else {
write_pcm_silence(s, buf, data_blocks);
}

write_midi_messages(s, buf, data_blocks,
desc->data_block_counter);
}

return pcm_frames;
}

int amdtp_dot_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir)
{
amdtp_stream_process_data_blocks_t process_data_blocks;
amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
enum cip_flags flags;

/* Use different mode between incoming/outgoing. */
// Use different mode between incoming/outgoing.
if (dir == AMDTP_IN_STREAM) {
flags = CIP_NONBLOCKING;
process_data_blocks = process_tx_data_blocks;
process_ctx_payloads = process_ir_ctx_payloads;
} else {
flags = CIP_BLOCKING;
process_data_blocks = process_rx_data_blocks;
process_ctx_payloads = process_it_ctx_payloads;
}

return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
process_data_blocks, sizeof(struct amdtp_dot));
process_ctx_payloads, sizeof(struct amdtp_dot));
}

void amdtp_dot_reset(struct amdtp_stream *s)
Expand Down
55 changes: 34 additions & 21 deletions sound/firewire/fireface/amdtp-ff.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,34 +112,47 @@ int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s,
return amdtp_stream_add_pcm_hw_constraints(s, runtime);
}

static unsigned int process_rx_data_blocks(struct amdtp_stream *s,
const struct pkt_desc *desc,
static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
const struct pkt_desc *descs,
unsigned int packets,
struct snd_pcm_substream *pcm)
{
unsigned int pcm_frames = 0;

if (pcm) {
write_pcm_s32(s, pcm, (__le32 *)desc->ctx_payload,
desc->data_blocks, pcm_frames);
pcm_frames = desc->data_blocks;
} else {
write_pcm_silence(s, (__le32 *)desc->ctx_payload,
desc->data_blocks);
int i;

for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = descs + i;
__le32 *buf = (__le32 *)desc->ctx_payload;
unsigned int data_blocks = desc->data_blocks;

if (pcm) {
write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
pcm_frames += data_blocks;
} else {
write_pcm_silence(s, buf, data_blocks);
}
}

return pcm_frames;
}

static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
const struct pkt_desc *desc,
struct snd_pcm_substream *pcm)
static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
const struct pkt_desc *descs,
unsigned int packets,
struct snd_pcm_substream *pcm)
{
unsigned int pcm_frames = 0;
int i;

if (pcm) {
read_pcm_s32(s, pcm, (__le32 *)desc->ctx_payload,
desc->data_blocks, pcm_frames);
pcm_frames = desc->data_blocks;
for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = descs + i;
__le32 *buf = (__le32 *)desc->ctx_payload;
unsigned int data_blocks = desc->data_blocks;

if (pcm) {
read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
pcm_frames += data_blocks;
}
}

return pcm_frames;
Expand All @@ -148,13 +161,13 @@ static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir)
{
amdtp_stream_process_data_blocks_t process_data_blocks;
amdtp_stream_process_ctx_payloads_t process_ctx_payloads;

if (dir == AMDTP_IN_STREAM)
process_data_blocks = process_tx_data_blocks;
process_ctx_payloads = process_ir_ctx_payloads;
else
process_data_blocks = process_rx_data_blocks;
process_ctx_payloads = process_it_ctx_payloads;

return amdtp_stream_init(s, unit, dir, CIP_NO_HEADER, 0,
process_data_blocks, sizeof(struct amdtp_ff));
process_ctx_payloads, sizeof(struct amdtp_ff));
}
Loading

0 comments on commit 9a738ad

Please sign in to comment.