All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] ALSA: firewire-tascam: support notification of
@ 2018-11-23  4:13 Takashi Sakamoto
  2018-11-23  4:13 ` [PATCH 1/5] ALSA: firewire-tascam: pick up data of state from tx isochronous pakcets Takashi Sakamoto
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2018-11-23  4:13 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: sbahling, alsa-devel, ffado-devel

Hi,

Units of TASCAM FireWire series transfer its state in tx isochronous
packets. The way to handle change of the state is a longstanding issue
since I firstly reveal the mechanism in this list[1].

In this time, Scott Bahling dedicates for further investigation to seek
better implementation[2][3][4]. Finally, we identified meaning of the
most of bits in the image of state, and decided which changes are worth
for userspace applications to handle as events.

This commit adds support notification of the events. Userspace
applications can handle the notification via ALSA hwdep interface.
Furthermore, they can retrieve image of the latest states via the
interface.

Changes from the initial proposal[5]:
 - obsolete usage of mmap(2) due to several disadvantages. Instead, use
   event queue for change notification, and add ioctl command to retrieve
   image of states.

Changes from the latest work[6]:
 - To reduce time in an interrupt context in which tx isochronous packets
   are handled, data in the event and the image is passed to userspace in
   big-endian order. Additionally, image of the states are passed to
   userspace in big-endian order as well. Userspace applications are
   responsible to convert the data in host-endianness order.
 - improve efficiency to copy batch of events to userspace in hwdep
   interface
 - rename structure and macro name.

This patchset is also available in my remote branch for backport purpose
to Linux v4.17 or later[7].

I've already prepare userspace implementation; libhinwa. A
'topic/firewire-tascam-pr' remote branch includes patchset for the
additional feature[8]. This library produces GObject class to handle the
event notification and emits GObject signal, and has a method
'HinawaSndTscm.get_state()', with enough consideration to endianness.
Developers can process change of state with these two APIs.

> Scott

As the above, I changed method name from 'HinawaSndTscm.get_status()'.
I'd like you to change your local implementation for 'hinawa-utils'.
Sorry to add further work to you.

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/094817.html
[2] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-September/140051.html
[3] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-October/140593.html
[4] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-November/141395.html
[5] https://github.com/takaswie/snd-firewire-improve/tree/topic/tascam-userspace
[6] https://github.com/takaswie/snd-firewire-improve/tree/topic/tascam-userspace-take3
[7] https://github.com/takaswie/snd-firewire-improve/tree/topic/tascam-userspace-pr
[8] https://github.com/takaswie/libhinawa/tree/topic/tascam-userspace-pr

Regards

Takashi Sakamoto (5):
  ALSA: firewire-tascam: pick up data of state from tx isochronous
    pakcets
  ALSA: firewire-tascam: add new hwdep ioctl command to get state image
  ALSA: firewire-tascam: queue events for change of control surface
  ALSA: firewire-tascam: apply small refactoring to handle several type
    of event for hwdep interface
  ALSA: firewire-tascam: notify events of change of state for userspace
    applications

 include/uapi/sound/firewire.h        |  20 +++++
 sound/firewire/tascam/amdtp-tascam.c |  51 +++++++++++-
 sound/firewire/tascam/tascam-hwdep.c | 115 +++++++++++++++++++++++----
 sound/firewire/tascam/tascam.h       |   9 +++
 4 files changed, 180 insertions(+), 15 deletions(-)

-- 
2.19.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/5] ALSA: firewire-tascam: pick up data of state from tx isochronous pakcets
  2018-11-23  4:13 [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
@ 2018-11-23  4:13 ` Takashi Sakamoto
  2018-11-23  4:13 ` [PATCH 2/5] ALSA: firewire-tascam: add new hwdep ioctl command to get state image Takashi Sakamoto
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2018-11-23  4:13 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: sbahling, alsa-devel, ffado-devel

Units of TASCAM FireWire series multiplex PCM frames and state of
control surface into the same tx isochronous packets. One isochronous
packet includes a part of the state in a quadlet data. An image of the
state consists of 64 quadlet data.

This commit demultiplexes the state from tx isochronous packets.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 include/uapi/sound/firewire.h        |  2 ++
 sound/firewire/tascam/amdtp-tascam.c | 17 ++++++++++++++++-
 sound/firewire/tascam/tascam.h       |  3 +++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/include/uapi/sound/firewire.h b/include/uapi/sound/firewire.h
index f0a547d86679..b9bc4bb1756b 100644
--- a/include/uapi/sound/firewire.h
+++ b/include/uapi/sound/firewire.h
@@ -88,4 +88,6 @@ struct snd_firewire_get_info {
  * Returns -EBUSY if the driver is already streaming.
  */
 
+#define SNDRV_FIREWIRE_TASCAM_STATE_COUNT	64
+
 #endif /* _UAPI_SOUND_FIREWIRE_H_INCLUDED */
diff --git a/sound/firewire/tascam/amdtp-tascam.c b/sound/firewire/tascam/amdtp-tascam.c
index ab482423c165..516cb931fd5e 100644
--- a/sound/firewire/tascam/amdtp-tascam.c
+++ b/sound/firewire/tascam/amdtp-tascam.c
@@ -117,6 +117,21 @@ int amdtp_tscm_add_pcm_hw_constraints(struct amdtp_stream *s,
 	return amdtp_stream_add_pcm_hw_constraints(s, runtime);
 }
 
+static void read_status_messages(struct amdtp_stream *s,
+				 __be32 *buffer, unsigned int data_blocks)
+{
+	struct snd_tscm *tscm = container_of(s, struct snd_tscm, tx_stream);
+	int i;
+
+	for (i = 0; i < data_blocks; i++) {
+		unsigned int index;
+
+		index = be32_to_cpu(buffer[0]) % SNDRV_FIREWIRE_TASCAM_STATE_COUNT;
+		tscm->state[index] = buffer[s->data_block_quadlets - 1];
+		buffer += s->data_block_quadlets;
+	}
+}
+
 static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
 					   __be32 *buffer,
 					   unsigned int data_blocks,
@@ -128,7 +143,7 @@ static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
 	if (data_blocks > 0 && pcm)
 		read_pcm_s32(s, pcm, buffer, data_blocks);
 
-	/* A place holder for control messages. */
+	read_status_messages(s, buffer, data_blocks);
 
 	return data_blocks;
 }
diff --git a/sound/firewire/tascam/tascam.h b/sound/firewire/tascam/tascam.h
index a5bd167eb5d9..c710496a99cf 100644
--- a/sound/firewire/tascam/tascam.h
+++ b/sound/firewire/tascam/tascam.h
@@ -89,6 +89,9 @@ struct snd_tscm {
 
 	/* For MIDI message outgoing transactions. */
 	struct snd_fw_async_midi_port out_ports[TSCM_MIDI_OUT_PORT_MAX];
+
+	// A cache of status information in tx isoc packets.
+	__be32 state[SNDRV_FIREWIRE_TASCAM_STATE_COUNT];
 };
 
 #define TSCM_ADDR_BASE			0xffff00000000ull
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/5] ALSA: firewire-tascam: add new hwdep ioctl command to get state image
  2018-11-23  4:13 [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
  2018-11-23  4:13 ` [PATCH 1/5] ALSA: firewire-tascam: pick up data of state from tx isochronous pakcets Takashi Sakamoto
@ 2018-11-23  4:13 ` Takashi Sakamoto
  2018-11-23  4:13 ` [PATCH 3/5] ALSA: firewire-tascam: queue events for change of control surface Takashi Sakamoto
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2018-11-23  4:13 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: sbahling, alsa-devel, ffado-devel

In a previous commit, ALSA firewire-tascam driver stores state image
from tx isochronous packets. This image includes states of knob, fader,
button of control surface, level of gain/volume of each physical
inputs/outputs, and so on. It's useful for userspace applications to
read whole of the image.

This commit adds a unique ioctl command for ALSA hwdep interface for the
purpose. For actual meaning of each bits in this image, please refer to
discussion in alsa-devel[1].

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-October/140785.html

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 include/uapi/sound/firewire.h        |  5 +++++
 sound/firewire/tascam/tascam-hwdep.c | 10 ++++++++++
 2 files changed, 15 insertions(+)

diff --git a/include/uapi/sound/firewire.h b/include/uapi/sound/firewire.h
index b9bc4bb1756b..012f81bf4750 100644
--- a/include/uapi/sound/firewire.h
+++ b/include/uapi/sound/firewire.h
@@ -66,6 +66,7 @@ union snd_firewire_event {
 #define SNDRV_FIREWIRE_IOCTL_GET_INFO _IOR('H', 0xf8, struct snd_firewire_get_info)
 #define SNDRV_FIREWIRE_IOCTL_LOCK      _IO('H', 0xf9)
 #define SNDRV_FIREWIRE_IOCTL_UNLOCK    _IO('H', 0xfa)
+#define SNDRV_FIREWIRE_IOCTL_TASCAM_STATE _IOR('H', 0xfb, struct snd_firewire_tascam_state)
 
 #define SNDRV_FIREWIRE_TYPE_DICE	1
 #define SNDRV_FIREWIRE_TYPE_FIREWORKS	2
@@ -90,4 +91,8 @@ struct snd_firewire_get_info {
 
 #define SNDRV_FIREWIRE_TASCAM_STATE_COUNT	64
 
+struct snd_firewire_tascam_state {
+	__be32 data[SNDRV_FIREWIRE_TASCAM_STATE_COUNT];
+};
+
 #endif /* _UAPI_SOUND_FIREWIRE_H_INCLUDED */
diff --git a/sound/firewire/tascam/tascam-hwdep.c b/sound/firewire/tascam/tascam-hwdep.c
index 4e4c1e9020e8..a80397116c48 100644
--- a/sound/firewire/tascam/tascam-hwdep.c
+++ b/sound/firewire/tascam/tascam-hwdep.c
@@ -123,6 +123,14 @@ static int hwdep_unlock(struct snd_tscm *tscm)
 	return err;
 }
 
+static int tscm_hwdep_state(struct snd_tscm *tscm, void __user *arg)
+{
+	if (copy_to_user(arg, tscm->state, sizeof(tscm->state)))
+		return -EFAULT;
+
+	return 0;
+}
+
 static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
 {
 	struct snd_tscm *tscm = hwdep->private_data;
@@ -147,6 +155,8 @@ static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file,
 		return hwdep_lock(tscm);
 	case SNDRV_FIREWIRE_IOCTL_UNLOCK:
 		return hwdep_unlock(tscm);
+	case SNDRV_FIREWIRE_IOCTL_TASCAM_STATE:
+		return tscm_hwdep_state(tscm, (void __user *)arg);
 	default:
 		return -ENOIOCTLCMD;
 	}
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/5] ALSA: firewire-tascam: queue events for change of control surface
  2018-11-23  4:13 [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
  2018-11-23  4:13 ` [PATCH 1/5] ALSA: firewire-tascam: pick up data of state from tx isochronous pakcets Takashi Sakamoto
  2018-11-23  4:13 ` [PATCH 2/5] ALSA: firewire-tascam: add new hwdep ioctl command to get state image Takashi Sakamoto
@ 2018-11-23  4:13 ` Takashi Sakamoto
  2018-11-23  4:13 ` [PATCH 4/5] ALSA: firewire-tascam: apply small refactoring to handle several type of event for hwdep interface Takashi Sakamoto
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2018-11-23  4:13 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: sbahling, alsa-devel, ffado-devel

Units of TASCAM FireWire series transfer image of states of the unit in
tx isochronous packets. Demultiplexing of the states from the packets
is done in software interrupt context regardless of any process context.
In a view of userspace applications, it needs to have notification
mechanism to catch change of the states.

This commit implements a queue to store events for the notification. The
image of states includes fluctuating data such as level of gain/volume
for physical input/output and position of knobs. Therefore the events
are queued corresponding to some control features only.

Furthermore, the queued events are planned to be consumed by userspace
applications via ALSA hwdep interface. This commit suppresses event
queueing when no applications open the hwdep interface.

However, the queue is maintained in an optimistic scenario, thus without
any care against overrrun. This is reasonable because target events are
useless just to handle PCM frames. It starts queueing when an usespace
application opens hwdep interface, thus it's expected to read the queued
events steadily.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 include/uapi/sound/firewire.h        |  6 +++++
 sound/firewire/tascam/amdtp-tascam.c | 34 +++++++++++++++++++++++++++-
 sound/firewire/tascam/tascam-hwdep.c |  2 ++
 sound/firewire/tascam/tascam.h       |  6 +++++
 4 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/include/uapi/sound/firewire.h b/include/uapi/sound/firewire.h
index 012f81bf4750..bb067efb09c6 100644
--- a/include/uapi/sound/firewire.h
+++ b/include/uapi/sound/firewire.h
@@ -53,6 +53,12 @@ struct snd_firewire_event_motu_notification {
 	__u32 message;	/* MOTU-specific bits. */
 };
 
+struct snd_firewire_tascam_change {
+	unsigned int index;
+	__be32 before;
+	__be32 after;
+};
+
 union snd_firewire_event {
 	struct snd_firewire_event_common            common;
 	struct snd_firewire_event_lock_status       lock_status;
diff --git a/sound/firewire/tascam/amdtp-tascam.c b/sound/firewire/tascam/amdtp-tascam.c
index 516cb931fd5e..0e8088c9ada9 100644
--- a/sound/firewire/tascam/amdtp-tascam.c
+++ b/sound/firewire/tascam/amdtp-tascam.c
@@ -121,13 +121,45 @@ static void read_status_messages(struct amdtp_stream *s,
 				 __be32 *buffer, unsigned int data_blocks)
 {
 	struct snd_tscm *tscm = container_of(s, struct snd_tscm, tx_stream);
+	bool used = READ_ONCE(tscm->hwdep->used);
 	int i;
 
 	for (i = 0; i < data_blocks; i++) {
 		unsigned int index;
+		__be32 before;
+		__be32 after;
 
 		index = be32_to_cpu(buffer[0]) % SNDRV_FIREWIRE_TASCAM_STATE_COUNT;
-		tscm->state[index] = buffer[s->data_block_quadlets - 1];
+		before = tscm->state[index];
+		after = buffer[s->data_block_quadlets - 1];
+
+		if (used && index > 4 && index < 16) {
+			__be32 mask;
+
+			if (index == 5)
+				mask = cpu_to_be32(~0x0000ffff);
+			else if (index == 6)
+				mask = cpu_to_be32(~0x0000ffff);
+			else if (index == 8)
+				mask = cpu_to_be32(~0x000f0f00);
+			else
+				mask = cpu_to_be32(~0x00000000);
+
+			if ((before ^ after) & mask) {
+				struct snd_firewire_tascam_change *entry =
+						&tscm->queue[tscm->push_pos];
+
+				spin_lock_irq(&tscm->lock);
+				entry->index = index;
+				entry->before = before;
+				entry->after = after;
+				if (++tscm->push_pos >= SND_TSCM_QUEUE_COUNT)
+					tscm->push_pos = 0;
+				spin_unlock_irq(&tscm->lock);
+			}
+		}
+
+		tscm->state[index] = after;
 		buffer += s->data_block_quadlets;
 	}
 }
diff --git a/sound/firewire/tascam/tascam-hwdep.c b/sound/firewire/tascam/tascam-hwdep.c
index a80397116c48..9afa827af05d 100644
--- a/sound/firewire/tascam/tascam-hwdep.c
+++ b/sound/firewire/tascam/tascam-hwdep.c
@@ -195,5 +195,7 @@ int snd_tscm_create_hwdep_device(struct snd_tscm *tscm)
 	hwdep->private_data = tscm;
 	hwdep->exclusive = true;
 
+	tscm->hwdep = hwdep;
+
 	return err;
 }
diff --git a/sound/firewire/tascam/tascam.h b/sound/firewire/tascam/tascam.h
index c710496a99cf..6a411ee0dcf1 100644
--- a/sound/firewire/tascam/tascam.h
+++ b/sound/firewire/tascam/tascam.h
@@ -62,6 +62,8 @@ struct snd_fw_async_midi_port {
 	int consume_bytes;
 };
 
+#define SND_TSCM_QUEUE_COUNT	16
+
 struct snd_tscm {
 	struct snd_card *card;
 	struct fw_unit *unit;
@@ -92,6 +94,10 @@ struct snd_tscm {
 
 	// A cache of status information in tx isoc packets.
 	__be32 state[SNDRV_FIREWIRE_TASCAM_STATE_COUNT];
+	struct snd_hwdep *hwdep;
+	struct snd_firewire_tascam_change queue[SND_TSCM_QUEUE_COUNT];
+	unsigned int pull_pos;
+	unsigned int push_pos;
 };
 
 #define TSCM_ADDR_BASE			0xffff00000000ull
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/5] ALSA: firewire-tascam: apply small refactoring to handle several type of event for hwdep interface
  2018-11-23  4:13 [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
                   ` (2 preceding siblings ...)
  2018-11-23  4:13 ` [PATCH 3/5] ALSA: firewire-tascam: queue events for change of control surface Takashi Sakamoto
@ 2018-11-23  4:13 ` Takashi Sakamoto
  2018-11-23  4:13 ` [PATCH 5/5] ALSA: firewire-tascam: notify events of change of state for userspace applications Takashi Sakamoto
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2018-11-23  4:13 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: sbahling, alsa-devel, ffado-devel

In later commits, ALSA firewire-tascam driver will allow userspace
applications to receive notifications about changes of device state,
transferred in tx isochronous packet. At present, all of drivers in ALSA
firewire stack have mechanism to notify change of status of packet
streaming, thus it needs to distinguish these two types of notification.

This commit is a preparation for the above.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/tascam/tascam-hwdep.c | 38 +++++++++++++++++++---------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/sound/firewire/tascam/tascam-hwdep.c b/sound/firewire/tascam/tascam-hwdep.c
index 9afa827af05d..8f34cede2e9f 100644
--- a/sound/firewire/tascam/tascam-hwdep.c
+++ b/sound/firewire/tascam/tascam-hwdep.c
@@ -16,14 +16,30 @@
 
 #include "tascam.h"
 
+static long tscm_hwdep_read_locked(struct snd_tscm *tscm, char __user *buf,
+				   long count, loff_t *offset)
+{
+	struct snd_firewire_event_lock_status event = {
+		.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
+	};
+
+	event.status = (tscm->dev_lock_count > 0);
+	tscm->dev_lock_changed = false;
+	count = min_t(long, count, sizeof(event));
+
+	spin_unlock_irq(&tscm->lock);
+
+	if (copy_to_user(buf, &event, count))
+		return -EFAULT;
+
+	return count;
+}
+
 static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
 		       loff_t *offset)
 {
 	struct snd_tscm *tscm = hwdep->private_data;
 	DEFINE_WAIT(wait);
-	union snd_firewire_event event = {
-		.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
-	};
 
 	spin_lock_irq(&tscm->lock);
 
@@ -37,15 +53,13 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
 		spin_lock_irq(&tscm->lock);
 	}
 
-	event.lock_status.status = (tscm->dev_lock_count > 0);
-	tscm->dev_lock_changed = false;
-
-	spin_unlock_irq(&tscm->lock);
-
-	count = min_t(long, count, sizeof(event.lock_status));
-
-	if (copy_to_user(buf, &event, count))
-		return -EFAULT;
+	// NOTE: The acquired lock should be released in callee side.
+	if (tscm->dev_lock_changed) {
+		count = tscm_hwdep_read_locked(tscm, buf, count, offset);
+	} else {
+		spin_unlock_irq(&tscm->lock);
+		count = 0;
+	}
 
 	return count;
 }
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/5] ALSA: firewire-tascam: notify events of change of state for userspace applications
  2018-11-23  4:13 [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
                   ` (3 preceding siblings ...)
  2018-11-23  4:13 ` [PATCH 4/5] ALSA: firewire-tascam: apply small refactoring to handle several type of event for hwdep interface Takashi Sakamoto
@ 2018-11-23  4:13 ` Takashi Sakamoto
  2018-11-23  4:19 ` [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
  2018-11-23 14:42 ` Takashi Iwai
  6 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2018-11-23  4:13 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: sbahling, alsa-devel, ffado-devel

In former commits, ALSA firewire-tascam driver queues events to notify
change of state of control surface to userspace via ALSA hwdep
interface.

This commit implements actual notification of the events. The events are
not governed by real time, thus no need to care underrun.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 include/uapi/sound/firewire.h        |  7 +++
 sound/firewire/tascam/amdtp-tascam.c |  2 +
 sound/firewire/tascam/tascam-hwdep.c | 65 +++++++++++++++++++++++++++-
 3 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/include/uapi/sound/firewire.h b/include/uapi/sound/firewire.h
index bb067efb09c6..ae12826ed641 100644
--- a/include/uapi/sound/firewire.h
+++ b/include/uapi/sound/firewire.h
@@ -12,6 +12,7 @@
 #define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE	0x4e617475
 #define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE	0x746e736c
 #define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION	0x64776479
+#define SNDRV_FIREWIRE_EVENT_TASCAM_CONTROL	0x7473636d
 
 struct snd_firewire_event_common {
 	unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */
@@ -59,12 +60,18 @@ struct snd_firewire_tascam_change {
 	__be32 after;
 };
 
+struct snd_firewire_event_tascam_control {
+	unsigned int type;
+	struct snd_firewire_tascam_change changes[0];
+};
+
 union snd_firewire_event {
 	struct snd_firewire_event_common            common;
 	struct snd_firewire_event_lock_status       lock_status;
 	struct snd_firewire_event_dice_notification dice_notification;
 	struct snd_firewire_event_efw_response      efw_response;
 	struct snd_firewire_event_digi00x_message   digi00x_message;
+	struct snd_firewire_event_tascam_control    tascam_control;
 	struct snd_firewire_event_motu_notification motu_notification;
 };
 
diff --git a/sound/firewire/tascam/amdtp-tascam.c b/sound/firewire/tascam/amdtp-tascam.c
index 0e8088c9ada9..a52d1f76c610 100644
--- a/sound/firewire/tascam/amdtp-tascam.c
+++ b/sound/firewire/tascam/amdtp-tascam.c
@@ -156,6 +156,8 @@ static void read_status_messages(struct amdtp_stream *s,
 				if (++tscm->push_pos >= SND_TSCM_QUEUE_COUNT)
 					tscm->push_pos = 0;
 				spin_unlock_irq(&tscm->lock);
+
+				wake_up(&tscm->hwdep_wait);
 			}
 		}
 
diff --git a/sound/firewire/tascam/tascam-hwdep.c b/sound/firewire/tascam/tascam-hwdep.c
index 8f34cede2e9f..0414abf5daa8 100644
--- a/sound/firewire/tascam/tascam-hwdep.c
+++ b/sound/firewire/tascam/tascam-hwdep.c
@@ -35,6 +35,65 @@ static long tscm_hwdep_read_locked(struct snd_tscm *tscm, char __user *buf,
 	return count;
 }
 
+static long tscm_hwdep_read_queue(struct snd_tscm *tscm, char __user *buf,
+				  long remained, loff_t *offset)
+{
+	char __user *pos = buf;
+	unsigned int type = SNDRV_FIREWIRE_EVENT_TASCAM_CONTROL;
+	struct snd_firewire_tascam_change *entries = tscm->queue;
+	long count;
+
+	// At least, one control event can be copied.
+	if (remained < sizeof(type) + sizeof(*entries)) {
+		spin_unlock_irq(&tscm->lock);
+		return -EINVAL;
+	}
+
+	// Copy the type field later.
+	count = sizeof(type);
+	remained -= sizeof(type);
+	pos += sizeof(type);
+
+	while (true) {
+		unsigned int head_pos;
+		unsigned int tail_pos;
+		unsigned int length;
+
+		if (tscm->pull_pos == tscm->push_pos)
+			break;
+		else if (tscm->pull_pos < tscm->push_pos)
+			tail_pos = tscm->push_pos;
+		else
+			tail_pos = SND_TSCM_QUEUE_COUNT;
+		head_pos = tscm->pull_pos;
+
+		length = (tail_pos - head_pos) * sizeof(*entries);
+		if (remained < length)
+			length = rounddown(remained, sizeof(*entries));
+		if (length == 0)
+			break;
+
+		spin_unlock_irq(&tscm->lock);
+		if (copy_to_user(pos, &entries[head_pos], length))
+			return -EFAULT;
+
+		spin_lock_irq(&tscm->lock);
+
+		tscm->pull_pos = tail_pos % SND_TSCM_QUEUE_COUNT;
+
+		count += length;
+		remained -= length;
+		pos += length;
+	}
+
+	spin_unlock_irq(&tscm->lock);
+
+	if (copy_to_user(buf, &type, sizeof(type)))
+		return -EFAULT;
+
+	return count;
+}
+
 static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
 		       loff_t *offset)
 {
@@ -43,7 +102,7 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
 
 	spin_lock_irq(&tscm->lock);
 
-	while (!tscm->dev_lock_changed) {
+	while (!tscm->dev_lock_changed && tscm->push_pos == tscm->pull_pos) {
 		prepare_to_wait(&tscm->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
 		spin_unlock_irq(&tscm->lock);
 		schedule();
@@ -56,6 +115,8 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
 	// NOTE: The acquired lock should be released in callee side.
 	if (tscm->dev_lock_changed) {
 		count = tscm_hwdep_read_locked(tscm, buf, count, offset);
+	} else if (tscm->push_pos != tscm->pull_pos) {
+		count = tscm_hwdep_read_queue(tscm, buf, count, offset);
 	} else {
 		spin_unlock_irq(&tscm->lock);
 		count = 0;
@@ -73,7 +134,7 @@ static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
 	poll_wait(file, &tscm->hwdep_wait, wait);
 
 	spin_lock_irq(&tscm->lock);
-	if (tscm->dev_lock_changed)
+	if (tscm->dev_lock_changed || tscm->push_pos != tscm->pull_pos)
 		events = EPOLLIN | EPOLLRDNORM;
 	else
 		events = 0;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/5] ALSA: firewire-tascam: support notification of
  2018-11-23  4:13 [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
                   ` (4 preceding siblings ...)
  2018-11-23  4:13 ` [PATCH 5/5] ALSA: firewire-tascam: notify events of change of state for userspace applications Takashi Sakamoto
@ 2018-11-23  4:19 ` Takashi Sakamoto
  2018-11-23 14:42 ` Takashi Iwai
  6 siblings, 0 replies; 8+ messages in thread
From: Takashi Sakamoto @ 2018-11-23  4:19 UTC (permalink / raw)
  To: clemens, tiwai; +Cc: ffado-devel, alsa-devel, sbahling

Oops, the subject line is truncated... It should be
"ALSA: firewire-tascam: support notification of change of state for
control surface". (My text editor works for the surplus.)

On Fri, Nov 23, 2018 at 01:13:02PM +0900, Takashi Sakamoto wrote:
> Hi,
> 
> Units of TASCAM FireWire series transfer its state in tx isochronous
> packets. The way to handle change of the state is a longstanding issue
> since I firstly reveal the mechanism in this list[1].
> 
> In this time, Scott Bahling dedicates for further investigation to seek
> better implementation[2][3][4]. Finally, we identified meaning of the
> most of bits in the image of state, and decided which changes are worth
> for userspace applications to handle as events.
> 
> This commit adds support notification of the events. Userspace
> applications can handle the notification via ALSA hwdep interface.
> Furthermore, they can retrieve image of the latest states via the
> interface.
> 
> Changes from the initial proposal[5]:
>  - obsolete usage of mmap(2) due to several disadvantages. Instead, use
>    event queue for change notification, and add ioctl command to retrieve
>    image of states.
> 
> Changes from the latest work[6]:
>  - To reduce time in an interrupt context in which tx isochronous packets
>    are handled, data in the event and the image is passed to userspace in
>    big-endian order. Additionally, image of the states are passed to
>    userspace in big-endian order as well. Userspace applications are
>    responsible to convert the data in host-endianness order.
>  - improve efficiency to copy batch of events to userspace in hwdep
>    interface
>  - rename structure and macro name.
> 
> This patchset is also available in my remote branch for backport purpose
> to Linux v4.17 or later[7].
> 
> I've already prepare userspace implementation; libhinwa. A
> 'topic/firewire-tascam-pr' remote branch includes patchset for the
> additional feature[8]. This library produces GObject class to handle the
> event notification and emits GObject signal, and has a method
> 'HinawaSndTscm.get_state()', with enough consideration to endianness.
> Developers can process change of state with these two APIs.
> 
> > Scott
> 
> As the above, I changed method name from 'HinawaSndTscm.get_status()'.
> I'd like you to change your local implementation for 'hinawa-utils'.
> Sorry to add further work to you.
> 
> [1] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/094817.html
> [2] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-September/140051.html
> [3] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-October/140593.html
> [4] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-November/141395.html
> [5] https://github.com/takaswie/snd-firewire-improve/tree/topic/tascam-userspace
> [6] https://github.com/takaswie/snd-firewire-improve/tree/topic/tascam-userspace-take3
> [7] https://github.com/takaswie/snd-firewire-improve/tree/topic/tascam-userspace-pr
> [8] https://github.com/takaswie/libhinawa/tree/topic/tascam-userspace-pr
> 
> Regards
> 
> Takashi Sakamoto (5):
>   ALSA: firewire-tascam: pick up data of state from tx isochronous
>     pakcets
>   ALSA: firewire-tascam: add new hwdep ioctl command to get state image
>   ALSA: firewire-tascam: queue events for change of control surface
>   ALSA: firewire-tascam: apply small refactoring to handle several type
>     of event for hwdep interface
>   ALSA: firewire-tascam: notify events of change of state for userspace
>     applications
> 
>  include/uapi/sound/firewire.h        |  20 +++++
>  sound/firewire/tascam/amdtp-tascam.c |  51 +++++++++++-
>  sound/firewire/tascam/tascam-hwdep.c | 115 +++++++++++++++++++++++----
>  sound/firewire/tascam/tascam.h       |   9 +++
>  4 files changed, 180 insertions(+), 15 deletions(-)
> 
> -- 
> 2.19.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/5] ALSA: firewire-tascam: support notification of
  2018-11-23  4:13 [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
                   ` (5 preceding siblings ...)
  2018-11-23  4:19 ` [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
@ 2018-11-23 14:42 ` Takashi Iwai
  6 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2018-11-23 14:42 UTC (permalink / raw)
  To: Takashi Sakamoto; +Cc: ffado-devel, alsa-devel, clemens, sbahling

On Fri, 23 Nov 2018 05:13:02 +0100,
Takashi Sakamoto wrote:
> 
> Hi,
> 
> Units of TASCAM FireWire series transfer its state in tx isochronous
> packets. The way to handle change of the state is a longstanding issue
> since I firstly reveal the mechanism in this list[1].
> 
> In this time, Scott Bahling dedicates for further investigation to seek
> better implementation[2][3][4]. Finally, we identified meaning of the
> most of bits in the image of state, and decided which changes are worth
> for userspace applications to handle as events.
> 
> This commit adds support notification of the events. Userspace
> applications can handle the notification via ALSA hwdep interface.
> Furthermore, they can retrieve image of the latest states via the
> interface.
> 
> Changes from the initial proposal[5]:
>  - obsolete usage of mmap(2) due to several disadvantages. Instead, use
>    event queue for change notification, and add ioctl command to retrieve
>    image of states.
> 
> Changes from the latest work[6]:
>  - To reduce time in an interrupt context in which tx isochronous packets
>    are handled, data in the event and the image is passed to userspace in
>    big-endian order. Additionally, image of the states are passed to
>    userspace in big-endian order as well. Userspace applications are
>    responsible to convert the data in host-endianness order.
>  - improve efficiency to copy batch of events to userspace in hwdep
>    interface
>  - rename structure and macro name.
> 
> This patchset is also available in my remote branch for backport purpose
> to Linux v4.17 or later[7].
> 
> I've already prepare userspace implementation; libhinwa. A
> 'topic/firewire-tascam-pr' remote branch includes patchset for the
> additional feature[8]. This library produces GObject class to handle the
> event notification and emits GObject signal, and has a method
> 'HinawaSndTscm.get_state()', with enough consideration to endianness.
> Developers can process change of state with these two APIs.
> 
> > Scott
> 
> As the above, I changed method name from 'HinawaSndTscm.get_status()'.
> I'd like you to change your local implementation for 'hinawa-utils'.
> Sorry to add further work to you.
> 
> [1] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/094817.html
> [2] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-September/140051.html
> [3] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-October/140593.html
> [4] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-November/141395.html
> [5] https://github.com/takaswie/snd-firewire-improve/tree/topic/tascam-userspace
> [6] https://github.com/takaswie/snd-firewire-improve/tree/topic/tascam-userspace-take3
> [7] https://github.com/takaswie/snd-firewire-improve/tree/topic/tascam-userspace-pr
> [8] https://github.com/takaswie/libhinawa/tree/topic/tascam-userspace-pr
> 
> Regards
> 
> Takashi Sakamoto (5):
>   ALSA: firewire-tascam: pick up data of state from tx isochronous
>     pakcets
>   ALSA: firewire-tascam: add new hwdep ioctl command to get state image
>   ALSA: firewire-tascam: queue events for change of control surface
>   ALSA: firewire-tascam: apply small refactoring to handle several type
>     of event for hwdep interface
>   ALSA: firewire-tascam: notify events of change of state for userspace
>     applications

Applied all five patches now.  Thanks.


Takashi

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-11-23 14:42 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-23  4:13 [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
2018-11-23  4:13 ` [PATCH 1/5] ALSA: firewire-tascam: pick up data of state from tx isochronous pakcets Takashi Sakamoto
2018-11-23  4:13 ` [PATCH 2/5] ALSA: firewire-tascam: add new hwdep ioctl command to get state image Takashi Sakamoto
2018-11-23  4:13 ` [PATCH 3/5] ALSA: firewire-tascam: queue events for change of control surface Takashi Sakamoto
2018-11-23  4:13 ` [PATCH 4/5] ALSA: firewire-tascam: apply small refactoring to handle several type of event for hwdep interface Takashi Sakamoto
2018-11-23  4:13 ` [PATCH 5/5] ALSA: firewire-tascam: notify events of change of state for userspace applications Takashi Sakamoto
2018-11-23  4:19 ` [PATCH 0/5] ALSA: firewire-tascam: support notification of Takashi Sakamoto
2018-11-23 14:42 ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.