12 Sep, 2020

1 commit

  • The tasklet is an old API that should be deprecated, usually can be
    converted to another decent API. In FireWire driver, a tasklet is
    still used for offloading the AMDTP PCM stream handling. It can be
    achieved gracefully with a work queued, too.

    This patch replaces the tasklet usage in firewire-lib driver with a
    simple work. The conversion is fairly straightforward but for the
    in_interrupt() checks that are replaced with the check using the
    current_work().

    Note that in_interrupt() in amdtp_packet tracepoint is still kept as
    is. This is the place that is probed by both softirq of 1394 OHCI and
    a user task of a PCM application, and the work handling is already
    filtered in amdtp_domain_stream_pcm_pointer().

    Tested-by: Takashi Sakamoto
    Acked-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20200909163659.21708-1-tiwai@suse.de
    Signed-off-by: Takashi Iwai

    Takashi Iwai
     

08 May, 2020

4 commits

  • In previous commit, the sequence of syt offset and the number of data
    blocks per packet is calculated for pool in AMDTP domain structure in
    advance of processing outgoing packets.

    This commit uses the sequence for outgoing packet processing to obsolete
    per-stream processing of the sequence.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20200508043635.349339-11-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • In current implementation, sequence of syt offset and the number of data
    blocks is generated when packets for outgoing stream are going to be
    queued.

    This commit generates and pools the sequence independently of the
    processing of outgoing packets for future extension.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20200508043635.349339-10-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • For future extension, storage is required to store packet sequence in
    incoming AMDTP stream to recover media clock for outgoing AMDTP stream.

    This commit adds the storage to AMDTP domain for this purpose. The
    packet sequence is represented by 'struct seq_desc' which has two
    members; syt_offset and the number of data blocks. The size of storage
    is decided according to the size of packet queue.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20200508043635.349339-9-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • In current implementation, AMDTP domain structure and AMDTP stream
    structure has one way of reference from the former to the latter. For
    future extension, bidirectional reference is needed.

    This commit adds a member into stream structure to refer to domain
    structure to which the stream belongs.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20200508043635.349339-4-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     

19 Oct, 2019

5 commits

  • Some devices have a quirk to postpone transmission of isoc packet for
    several dozen or hundred isoc cycles since configured to transmit.
    Furthermore, some devices have a quirk to transmit isoc packet with
    discontinued data of its header.

    In 1394 OHCI specification, software allows to start isoc context with
    certain isoc cycle. Linux firewire subsystem has kernel API to use it
    as well.

    This commit uses the functionality of 1394 OHCI controller to handle
    the quirks. At present, this feature is convenient to ALSA bebob and
    fireface driver. As a result, some devices can be safely handled, as
    long as I know:
    - MAudio FireWire solo
    - MAudio ProFire Lightbridge
    - MAudio FireWire 410
    - Roland FA-66

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20191018061911.24909-7-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • This commit changes AMDTP domain to run on an IT context of 1394 OHCI as
    IRQ target. No hardware interrupt is scheduled for the other isoc
    contexts. All of the isoc context are processed in a callback for an isoc
    context of IRQ target.

    The IRQ target is automatically selected from a list of AMDTP streams,
    thus users of AMDTP domain should add an AMDTP stream for IT context
    at least.

    The reason to select IT context as IRQ target is that the IT context
    runs on local 1394 OHCI controller and it can be used as reliable,
    constant IRQ generator. On the other hand, IR context can include skip
    cycle according to isoc packet transferred by device.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20191018061911.24909-6-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • An isoc context for AMDTP stream is flushed to queue packet
    by a call of pcm.ack. This commit extends this for AMDTP
    domain.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20191018061911.24909-4-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • An isoc context for AMDTP stream is flushed to queue packet
    by a call of pcm.pointer. This commit extends this for AMDTP
    domain.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20191018061911.24909-3-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • This commit is a preparation to handle several IR/IT contexts in the same
    domain by tasklet context for one of the IT context. Such IT context is
    stored to AMDTP domain structure as 'irq_target'.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20191018061911.24909-2-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     

18 Oct, 2019

2 commits

  • ALSA IEC 61883-1/6 packet streaming engine controls 1394 OHCI controller
    to generate hardware IRQ for fixed number of isochronous packets (=16)
    since its first commit.

    This commit allow the engine to generate it for variable period according
    to the number of event to handle. For outgoing stream, internal
    calculator is used to check the accumulated events. For incoming stream,
    the number of data block in the packet of stream is used to check the
    accumulated events. When it's unavailable, fixed number of packet
    roughly calculated in advance is used instead of event counting.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20191017155424.885-11-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • The number of packets in packet buffer has been fixed number (=48) since
    first commit of ALSA IEC 61883-1/6 packet streaming engine.

    This commit allows the engine to use variable number of packets in the
    buffer. The size is calculated by a parameter in AMDTP domain structure
    surely to store the number of events in the packets of buffer. Although
    the value of parameter is expected to come from 'period size' parameter
    of PCM substream, at present 48 is still used.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20191017155424.885-2-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     

17 Oct, 2019

1 commit

  • In IEC 61883-6, it's called as 'event' what has presentation time
    represented by timestamp in CIP header. Although the ratio of the number
    of event against the number of data block is different depending on
    event data type represented by the specific field in CIP header, it's
    just one in the most cases supported by ALSA IEC 61883-1/6 engine.

    In 1394 OHCI specification, applications can schedule hardware IRQ
    by configuring descriptor with IRQ flag for packet against each
    isochronous cycle. For future commit, I use the hardware IRQ for
    isoc IT context to acknowledge the elapse of PCM period for both
    playback/capture directions on AMDTP streams in the same domain.

    This commit is a preparation for the above idea. This commit adds
    a member into AMDTP domain structure to record the number of PCM frames.

    Signed-off-by: Takashi Sakamoto
    Link: https://lore.kernel.org/r/20191007110532.30270-2-o-takashi@sakamocchi.jp
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     

06 Aug, 2019

5 commits


22 Jul, 2019

7 commits

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

    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • This commit changes signature of callback function to call data block
    processing layer with packet descriptor. At present, the layer is called
    per packet.

    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • In current implementation of ALSA IEC 61883-1/6 packet streaming engine,
    16 packets are handled in one interrupt of isochronous context of OHCI
    1394.

    Overall packet processing runs for each. However, this is not better in
    a point to split the processing into several parts.

    This commit is an attempt to add intermediate representation for
    parameters required for the parts.

    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • In a previous commit, the variable passed from packet streaming layer
    for syt variable is useless. This commit obsoletes it.

    In my future work, the syt information is passed to data block processing
    layer by another way.

    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • Some protocols don't use syt field of CIP header to represent
    presentation timestamp. For such protocol, ALSA IEC 61883-1/6
    packet streaming engine uses a pointer into local variable for
    the value of syt to call data block processing layer. However,
    it can decide the value when initializing packet streaming
    layer.

    This commit adds 'syt_override' member for packet streaming
    layer.

    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • This is a preparation for future commit that 'struct
    amdtp_stream.data_block_count' does not represent the value of
    data block count for current data block.

    However, data block count is required for calculation of sequence index
    in sequence-multiplied data channel. Some of data block processing layer
    require it; e.g. for AM824 data block.

    This commit passes data block count to the processing layer.

    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     
  • Recent firmware for Fireworks board module have a quirk to start
    transmission of CIP with non-zero value for its data block counter.
    In current implementation of ALSA firewire stack, the quirk is handled
    by 'struct amdtp_stream.ctx_data.tx.first_dbc' with value 0x02. However,
    the value comes from reverse engineering. It's better to handle this
    quirk without the explicit value.

    In a process to parse CIP header, the quirk of data block counter
    affects decision of sequence index in sequence-multiplexed data channel;
    i.e. MIDI conformant data channel. In Fireworks, the index is decided
    by the number of data blocks from top of the same CIP, thus the value
    of data block counter is useless.

    This commit adds CIP_UNALIGHED_DBC flag and obsoletes the explicit
    value for this quirk.

    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     

24 May, 2019

1 commit


23 May, 2019

3 commits


22 May, 2019

1 commit


07 Nov, 2017

1 commit


02 Nov, 2017

1 commit

  • Many source files in the tree are missing licensing information, which
    makes it harder for compliance tools to determine the correct license.

    By default all files without license information are under the default
    license of the kernel, which is GPL version 2.

    Update the files which contain no license information with the 'GPL-2.0'
    SPDX license identifier. The SPDX identifier is a legally binding
    shorthand, which can be used instead of the full boiler plate text.

    This patch is based on work done by Thomas Gleixner and Kate Stewart and
    Philippe Ombredanne.

    How this work was done:

    Patches were generated and checked against linux-4.14-rc6 for a subset of
    the use cases:
    - file had no licensing information it it.
    - file was a */uapi/* one with no licensing information in it,
    - file was a */uapi/* one with existing licensing information,

    Further patches will be generated in subsequent months to fix up cases
    where non-standard license headers were used, and references to license
    had to be inferred by heuristics based on keywords.

    The analysis to determine which SPDX License Identifier to be applied to
    a file was done in a spreadsheet of side by side results from of the
    output of two independent scanners (ScanCode & Windriver) producing SPDX
    tag:value files created by Philippe Ombredanne. Philippe prepared the
    base worksheet, and did an initial spot review of a few 1000 files.

    The 4.13 kernel was the starting point of the analysis with 60,537 files
    assessed. Kate Stewart did a file by file comparison of the scanner
    results in the spreadsheet to determine which SPDX license identifier(s)
    to be applied to the file. She confirmed any determination that was not
    immediately clear with lawyers working with the Linux Foundation.

    Criteria used to select files for SPDX license identifier tagging was:
    - Files considered eligible had to be source code files.
    - Make and config files were included as candidates if they contained >5
    lines of source
    - File already had some variant of a license header in it (even if
    Reviewed-by: Philippe Ombredanne
    Reviewed-by: Thomas Gleixner
    Signed-off-by: Greg Kroah-Hartman

    Greg Kroah-Hartman
     

25 Oct, 2017

1 commit

  • …READ_ONCE()/WRITE_ONCE()

    Please do not apply this to mainline directly, instead please re-run the
    coccinelle script shown below and apply its output.

    For several reasons, it is desirable to use {READ,WRITE}_ONCE() in
    preference to ACCESS_ONCE(), and new code is expected to use one of the
    former. So far, there's been no reason to change most existing uses of
    ACCESS_ONCE(), as these aren't harmful, and changing them results in
    churn.

    However, for some features, the read/write distinction is critical to
    correct operation. To distinguish these cases, separate read/write
    accessors must be used. This patch migrates (most) remaining
    ACCESS_ONCE() instances to {READ,WRITE}_ONCE(), using the following
    coccinelle script:

    ----
    // Convert trivial ACCESS_ONCE() uses to equivalent READ_ONCE() and
    // WRITE_ONCE()

    // $ make coccicheck COCCI=/home/mark/once.cocci SPFLAGS="--include-headers" MODE=patch

    virtual patch

    @ depends on patch @
    expression E1, E2;
    @@

    - ACCESS_ONCE(E1) = E2
    + WRITE_ONCE(E1, E2)

    @ depends on patch @
    expression E;
    @@

    - ACCESS_ONCE(E)
    + READ_ONCE(E)
    ----

    Signed-off-by: Mark Rutland <mark.rutland@arm.com>
    Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: davem@davemloft.net
    Cc: linux-arch@vger.kernel.org
    Cc: mpe@ellerman.id.au
    Cc: shuah@kernel.org
    Cc: snitzer@redhat.com
    Cc: thor.thayer@linux.intel.com
    Cc: tj@kernel.org
    Cc: viro@zeniv.linux.org.uk
    Cc: will.deacon@arm.com
    Link: http://lkml.kernel.org/r/1508792849-3115-19-git-send-email-paulmck@linux.vnet.ibm.com
    Signed-off-by: Ingo Molnar <mingo@kernel.org>

    Mark Rutland
     

20 Jun, 2017

1 commit


19 Jun, 2017

1 commit

  • At Linux v3.5, packet processing can be done in process context of ALSA
    PCM application as well as software IRQ context for OHCI 1394. Below is
    an example of the callgraph (some calls are omitted).

    ioctl(2) with e.g. HWSYNC
    (sound/core/pcm_native.c)
    ->snd_pcm_common_ioctl1()
    ->snd_pcm_hwsync()
    ->snd_pcm_stream_lock_irq
    (sound/core/pcm_lib.c)
    ->snd_pcm_update_hw_ptr()
    ->snd_pcm_udpate_hw_ptr0()
    ->struct snd_pcm_ops.pointer()
    (sound/firewire/*)
    = Each handler on drivers in ALSA firewire stack
    (sound/firewire/amdtp-stream.c)
    ->amdtp_stream_pcm_pointer()
    (drivers/firewire/core-iso.c)
    ->fw_iso_context_flush_completions()
    ->struct fw_card_driver.flush_iso_completion()
    (drivers/firewire/ohci.c)
    = flush_iso_completions()
    ->struct fw_iso_context.callback.sc
    (sound/firewire/amdtp-stream.c)
    = in_stream_callback() or out_stream_callback()
    ->...
    ->snd_pcm_stream_unlock_irq

    When packet queueing error occurs or detecting invalid packets in
    'in_stream_callback()' or 'out_stream_callback()', 'snd_pcm_stop_xrun()'
    is called on local CPU with disabled IRQ.

    (sound/firewire/amdtp-stream.c)
    in_stream_callback() or out_stream_callback()
    ->amdtp_stream_pcm_abort()
    ->snd_pcm_stop_xrun()
    ->snd_pcm_stream_lock_irqsave()
    ->snd_pcm_stop()
    ->snd_pcm_stream_unlock_irqrestore()

    The process is stalled on the CPU due to attempt to acquire recursive lock.

    [ 562.630853] INFO: rcu_sched detected stalls on CPUs/tasks:
    [ 562.630861] 2-...: (1 GPs behind) idle=37d/140000000000000/0 softirq=38323/38323 fqs=7140
    [ 562.630862] (detected by 3, t=15002 jiffies, g=21036, c=21035, q=5933)
    [ 562.630866] Task dump for CPU 2:
    [ 562.630867] alsa-source-OXF R running task 0 6619 1 0x00000008
    [ 562.630870] Call Trace:
    [ 562.630876] ? vt_console_print+0x79/0x3e0
    [ 562.630880] ? msg_print_text+0x9d/0x100
    [ 562.630883] ? up+0x32/0x50
    [ 562.630885] ? irq_work_queue+0x8d/0xa0
    [ 562.630886] ? console_unlock+0x2b6/0x4b0
    [ 562.630888] ? vprintk_emit+0x312/0x4a0
    [ 562.630892] ? dev_vprintk_emit+0xbf/0x230
    [ 562.630895] ? do_sys_poll+0x37a/0x550
    [ 562.630897] ? dev_printk_emit+0x4e/0x70
    [ 562.630900] ? __dev_printk+0x3c/0x80
    [ 562.630903] ? _raw_spin_lock+0x20/0x30
    [ 562.630909] ? snd_pcm_stream_lock+0x31/0x50 [snd_pcm]
    [ 562.630914] ? _snd_pcm_stream_lock_irqsave+0x2e/0x40 [snd_pcm]
    [ 562.630918] ? snd_pcm_stop_xrun+0x16/0x70 [snd_pcm]
    [ 562.630922] ? in_stream_callback+0x3e6/0x450 [snd_firewire_lib]
    [ 562.630925] ? handle_ir_packet_per_buffer+0x8e/0x1a0 [firewire_ohci]
    [ 562.630928] ? ohci_flush_iso_completions+0xa3/0x130 [firewire_ohci]
    [ 562.630932] ? fw_iso_context_flush_completions+0x15/0x20 [firewire_core]
    [ 562.630935] ? amdtp_stream_pcm_pointer+0x2d/0x40 [snd_firewire_lib]
    [ 562.630938] ? pcm_capture_pointer+0x19/0x20 [snd_oxfw]
    [ 562.630943] ? snd_pcm_update_hw_ptr0+0x47/0x3d0 [snd_pcm]
    [ 562.630945] ? poll_select_copy_remaining+0x150/0x150
    [ 562.630947] ? poll_select_copy_remaining+0x150/0x150
    [ 562.630952] ? snd_pcm_update_hw_ptr+0x10/0x20 [snd_pcm]
    [ 562.630956] ? snd_pcm_hwsync+0x45/0xb0 [snd_pcm]
    [ 562.630960] ? snd_pcm_common_ioctl1+0x1ff/0xc90 [snd_pcm]
    [ 562.630962] ? futex_wake+0x90/0x170
    [ 562.630966] ? snd_pcm_capture_ioctl1+0x136/0x260 [snd_pcm]
    [ 562.630970] ? snd_pcm_capture_ioctl+0x27/0x40 [snd_pcm]
    [ 562.630972] ? do_vfs_ioctl+0xa3/0x610
    [ 562.630974] ? vfs_read+0x11b/0x130
    [ 562.630976] ? SyS_ioctl+0x79/0x90
    [ 562.630978] ? entry_SYSCALL_64_fastpath+0x1e/0xad

    This commit fixes the above bug. This assumes two cases:
    1. Any error is detected in software IRQ context of OHCI 1394 context.
    In this case, PCM substream should be aborted in packet handler. On the
    other hand, it should not be done in any process context. TO distinguish
    these two context, use 'in_interrupt()' macro.
    2. Any error is detect in process context of ALSA PCM application.
    In this case, PCM substream should not be aborted in packet handler
    because PCM substream lock is acquired. The task to abort PCM substream
    should be done in ALSA PCM core. For this purpose, SNDRV_PCM_POS_XRUN is
    returned at 'struct snd_pcm_ops.pointer()'.

    Suggested-by: Clemens Ladisch
    Fixes: e9148dddc3c7("ALSA: firewire-lib: flush completed packets when reading PCM position")
    Cc: # 4.9+
    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     

07 Jun, 2017

1 commit

  • In recent commit for ALSA PCM core, some arrangement is done for
    'struct snd_pcm_ops.ack' callback. This is called when appl_ptr is
    explicitly moved in intermediate buffer for PCM frames, except for
    some cases described later.

    For drivers in ALSA firewire stack, usage of this callback has a merit to
    reduce latency between time of PCM frame queueing and handling actual
    packets in recent isochronous cycle, because no need to wait for software
    IRQ context from isochronous context of OHCI 1394.

    If this works well in a case that mapped page frame is used for the
    intermediate buffer, user process should execute some commands for ioctl(2)
    to tell the number of handled PCM frames in the intermediate buffer just
    after handling them. Therefore, at present, with a combination of below
    conditions, this doesn't work as expected and user process should wait for
    the software IRQ context as usual:
    - when ALSA PCM core judges page frame mapping is available for status
    data (struct snd_pcm_mmap_status) and control data
    (struct snd_pcm_mmap_control).
    - user process handles PCM frames by loop just with 'snd_pcm_mmap_begin()'
    and 'snd_pcm_mmap_commit()'.
    - user process uses PCM hw plugin in alsa-lib to operate I/O without
    'sync_ptr_ioctl' option.

    Unfortunately, major use case include these three conditions.

    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     

12 Apr, 2017

1 commit

  • During packet streaming, maximum length of payload for isochronous packet
    is invariable, therefore no need to recalculate. Current ALSA IEC 61883-1/6
    engine calls a function to calculate it 8,000 or more times per second
    for incoming packet processing.

    This commit adds a member to have maximum length of payload into 'struct
    amdtp_stream', to reduces the function calls. At first callback from
    isochronous context, the length is calculated and stored for later
    processing.

    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     

06 Apr, 2017

1 commit

  • As long as investigating Fireface 400, IEC 61883-1/6 is not applied to
    its packet streaming protocol. Remarks of the specific protocol are:
    * Each packet doesn't include CIP headers.
    * 64,0 and 128,0 kHz are supported.
    * The device doesn't necessarily transmit 8,000 packets per second.
    * 0, 1, 2, 3 are used as tag for rx isochronous packets, however 0 is
    used for tx isochronous packets.

    On the other hand, there's a common feature. The number of data blocks
    transferred in a second is the same as sampling transmission frequency.
    Current ALSA IEC 61883-1/6 engine already has a method to calculate it and
    this driver can utilize it for rx packets, as well as tx packets.

    This commit adds support for the transferring protocol. CIP_NO_HEADERS
    flag is newly added. When this flag is set:
    * Both of 0 (without CIP header) and 1 (with CIP header) are used as tag
    to handle incoming isochronous packet.
    * 0 (without CIP header) is used as tag to transfer outgoing isochronous
    packet.
    * Skip CIP header evaluation.
    * Use unique way to calculate the quadlets of isochronous packet payload.

    In ALSA PCM interface, 128.0 kHz is not supported, and the ALSA
    IEC 61883-1/6 engine doesn't support 64.0 kHz. These modes are dropped.

    The sequence of rx packet has a remarkable quirk about tag. This will be
    described in later commits.

    Signed-off-by: Takashi Sakamoto
    Signed-off-by: Takashi Iwai

    Takashi Sakamoto
     

28 Mar, 2017

2 commits