1. 10 5月, 2016 1 次提交
    • T
      ALSA: firewire-lib: handle IT/IR contexts in each software interrupt context · dec63cc8
      Takashi Sakamoto 提交于
      In clause 6.3 of IEC 61883-6:2000, there's an explanation about processing
      of presentation timestamp. In the clause, we can see "If a function block
      receives a CIP, processes it and subsequently re-transmits it, then the
      SYT of the outgoing CIP shall be the sum of the incoming SYT and the
      processing delay." ALSA firewire stack has an implementation to partly
      satisfy this specification. Developers assumed the stack to perform as an
      Audio function block[1].
      
      Following to the assumption, current implementation of ALSA firewire stack
      use one software interrupt context to handle both of in/out packets. In
      most case, this is processed in 1394 OHCI IR context independently of the
      opposite context. Thus, this implementation uses longer CPU time in the
      software interrupt context. This is not better for whole system.
      
      Against the assumption, I confirmed that each ASIC for IEC 61883-1/6
      doesn't necessarily expect it to the stack. Thus, current implementation
      of ALSA firewire stack includes over-engineering.
      
      This commit purges the implementation. As a result, packets of one
      direction are handled in one software interrupt context and spends
      minimum CPU time.
      
      [1] [alsa-devel] [PATCH 0/8] [RFC] new driver for Echo Audio's Fireworks based devices
      http://mailman.alsa-project.org/pipermail/alsa-devel/2013-June/062660.htmlSigned-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      dec63cc8
  2. 09 5月, 2016 3 次提交
    • T
      ALSA: firewire-lib: add tracepoints to dump a part of isochronous packet data · 0c95c1d6
      Takashi Sakamoto 提交于
      When audio and music units have some quirks in their sequence of packet,
      it's really hard for non-owners to identify the quirks. Although developers
      need dumps for sequence of packets, it's difficult for users who have no
      knowledges and no equipments for this purpose.
      
      This commit adds tracepoints for this situation. When users encounter
      the issue, they can dump a part of packet data via Linux tracing framework
      as long as using drivers in ALSA firewire stack.
      
      Additionally, tracepoints for outgoing packets will be our help to check
      and debug packet processing of ALSA firewire stack.
      
      This commit newly adds 'snd_firewire_lib' subsystem with 'in_packet' and
      'out_packet' events. In the events, some attributes of packets and the
      index of packet managed by this module are recorded per packet.
      
      This is an usage:
      
      $ trace-cmd record -e snd_firewire_lib:out_packet \
                         -e snd_firewire_lib:in_packet
      /sys/kernel/tracing/events/snd_firewire_lib/out_packet/filter
      /sys/kernel/tracing/events/snd_firewire_lib/in_packet/filter
      Hit Ctrl^C to stop recording
      ^C
      $ trace-cmd report trace.dat
      ...
      23647.033934: in_packet:  01 4073 ffc0 ffc1 00 000f0040 9001b2d1 122 44
      23647.033936: in_packet:  01 4074 ffc0 ffc1 00 000f0048 9001c83b 122 45
      23647.033937: in_packet:  01 4075 ffc0 ffc1 00 000f0050 9001ffff 002 46
      23647.033938: in_packet:  01 4076 ffc0 ffc1 00 000f0050 9001e1a6 122 47
      23647.035426: out_packet: 01 4123 ffc1 ffc0 01 010f00d0 9001fb40 122 17
      23647.035428: out_packet: 01 4124 ffc1 ffc0 01 010f00d8 9001ffff 002 18
      23647.035429: out_packet: 01 4125 ffc1 ffc0 01 010f00d8 900114aa 122 19
      23647.035430: out_packet: 01 4126 ffc1 ffc0 01 010f00e0 90012a15 122 20
      (Here, some common fields are omitted so that a line to be within 80
      characters.)
      ...
      
      One line represent one packet. The legend for the last nine fields is:
       - The second of cycle scheduled for the packet
       - The count of cycle scheduled for the packet
       - The ID of node as source (hex)
        - Some devices transfer packets with invalid source node ID in their CIP
          header.
       - The ID of node as destination (hex)
        - The value is not in CIP header of packets.
       - The value of isochronous channel
       - The first quadlet of CIP header (hex)
       - The second quadlet of CIP header (hex)
       - The number of included quadlets
       - The index of packet in a buffer maintained by this module
      
      This is an example to parse these lines from text file by Python3 script:
      
      \#!/usr/bin/env python3
      import sys
      
      def parse_ts(second, cycle, syt):
          offset = syt & 0xfff
          syt >>= 12
          if cycle & 0x0f > syt:
              cycle += 0x10
          cycle &= 0x1ff0
          cycle |= syt
          second += cycle // 8000
          cycle %= 8000
          # In CYCLE_TIMER of 1394 OHCI, second is represented in 8 bit.
          second %= 128
          return (second, cycle, offset)
      
      def calc_ts(second, cycle, offset):
          ts = offset
          ts += cycle * 3072
          # In DMA descriptor of 1394 OHCI, second is represented in 3 bit.
          ts += (second % 8) * 8000 * 3072
          return ts
      
      def subtract_ts(minuend, subtrahend):
          # In DMA descriptor of 1394 OHCI, second is represented in 3 bit.
          if minuend < subtrahend:
              minuend += 8 * 8000 * 3072
          return minuend - subtrahend
      
      if len(sys.argv) != 2:
          print('At least, one argument is required for packet dump.')
          sys.exit()
      
      filename = sys.argv[1]
      
      data = []
      
      prev = 0
      with open(filename, 'r') as f:
          for line in f:
              pos = line.find('packet:')
              if pos < 0:
                  continue
      
              pos += len('packet:')
              line = line[pos:].strip()
              fields = line.split(' ')
      
              datum = []
      
              datum.append(fields[8])
      
              syt = int(fields[6][4:], 16)
      
              # Empty packet in IEC 61883-1, or NODATA in IEC 61883-6
              if syt == 0xffff:
                  data_blocks = 0
              else:
                  payload_size = int(fields[7], 10)
                  data_block_size = int(fields[5][2:4], 16)
                  data_blocks = (payload_size - 2) / data_block_size
              datum.append(data_blocks)
      
              second = int(fields[0], 10)
              cycle = int(fields[1], 10)
              start = (second << 25) | (cycle << 12)
              datum.append('0x{0:08x}'.format(start))
              start = calc_ts(second, cycle, 0)
      
              datum.append("0x" + fields[5])
              datum.append("0x" + fields[6])
      
              if syt == 0xffff:
                  second = 0
                  cycle = 0
                  tick = 0
              else:
                  second, cycle, tick = parse_ts(second, cycle, syt)
              ts = calc_ts(second, cycle, tick)
              datum.append(start)
              datum.append(ts)
              if ts == 0:
                  datum.append(0)
                  datum.append(0)
              else:
                  # Usual case, or a case over 8 seconds.
                  if ts > start or start > 7 * 8000 * 3072:
                      datum.append(subtract_ts(ts, start))
                      if ts > prev or start > 7 * 8000 * 3072:
                          gap = subtract_ts(ts, prev)
                          datum.append(gap)
                      else:
                          datum.append('backward')
                  else:
                      datum.append('invalid')
                  prev = ts
      
              data.append(datum)
      
      sys.exit()
      
      The data variable includes array with these elements:
      - The index of the packet
      - The number of data blocks in the packet
      - The value of cycle count (hex)
      - The value of CIP header 1 (hex)
      - The value of CIP header 2 (hex)
      - The value of cycle count (tick)
      - The value of calculated presentation timestamp (tick)
      - The offset between the cycle count and presentation timestamp
      - The elapsed ticks from the previous presentation timestamp
      Signed-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      0c95c1d6
    • T
      ALSA: firewire-lib: compute the value of second field in cycle count for IR context · f90e2ded
      Takashi Sakamoto 提交于
      In callback function of isochronous context, modules can queue packets to
      indicated isochronous cycles. Although the cycle to queue a packet is
      deterministic by calculation, this module doesn't implement the calculation
      because it's useless for processing.
      
      In future, the cycle count is going to be printed with the other parameters
      for debugging. This commit is the preparation. The cycle count is computed
      by cycle unit, and correctly arranged to corresponding packets. The
      calculated count is used in later commit.
      Signed-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      f90e2ded
    • T
      ALSA: firewire-lib: compute the value of second field in cycle count for IT context · 73fc7f08
      Takashi Sakamoto 提交于
      In callback function of isochronous context, u32 variable is passed for
      cycle count. The value of this variable comes from DMA descriptors of 1394
      Open Host Controller Interface (1394 OHCI). In the specification, DMA
      descriptors transport lower 3 bits for second field and full cycle field in
      16 bits field, therefore 16 bits of the u32 variable are available. The
      value for second is modulo 8, and the value for cycle is modulo 8,000.
      
      Currently, ALSA firewire-lib module don't use the value of the second
      field, because the value is useless to calculate presentation timestamp in
      IEC 61883-6. However, the value may be useful for debugging. In later
      commit, it will be printed with the other parameters for debugging.
      
      This commit makes this module to handle the whole cycle count including
      second. The value is calculated by cycle unit. The existed code is already
      written with ignoring the value of second, thus this commit causes no
      issues.
      Signed-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      73fc7f08
  3. 31 3月, 2016 1 次提交
  4. 12 10月, 2015 1 次提交
    • T
      ALSA: firewire-lib: continue packet processing at detecting wrong CIP headers · 2a7e1713
      Takashi Sakamoto 提交于
      In firewire-lib, isochronous packet streaming is stopped when detecting
      wrong value for FMT field of CIP headers. Although this is appropriate
      to IEC 61883-1 and 6, some BeBoB based devices with vendors' customization
      use invalid value to FMT field of CIP headers in the beginning of
      streaming.
      
      $ journalctl
        snd-bebob fw1.0: Detect unexpected protocol: 01000000 8000ffff
      
      I got this log with M-Audio FireWire 1814. In this line, the value of FMT
      field is 0x00, while it should be 0x10 in usual AMDTP.
      
      Except for the beginning, these devices continue to transfer packets with
      valid value for FMT field, except for the beginning. Therefore, in this
      case, firewire-lib should continue to process packets. The former
      implementation of firewire-lib performs it.
      
      This commit loosens the handling of wrong value, to continue packet
      processing in the case.
      
      Fixes: 414ba022 ('ALSA: firewire-lib: add support arbitrary value for fmt/fdf fields in CIP header')
      Signed-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      2a7e1713
  5. 29 9月, 2015 12 次提交
  6. 05 8月, 2015 1 次提交
    • T
      ALSA: fireworks/firewire-lib: add support for recent firmware quirk · 18f5ed36
      Takashi Sakamoto 提交于
      Fireworks uses TSB43CB43(IceLynx-Micro) as its IEC 61883-1/6 interface.
      This chip includes ARM7 core, and loads and runs program. The firmware
      is stored in on-board memory and loaded every powering-on from it.
      
      Echo Audio ships several versions of firmwares for each model. These
      firmwares have each quirk and the quirk changes a sequence of packets.
      
      As long as I investigated, AudioFire2/AudioFire4/AudioFirePre8 have a
      quirk to transfer a first packet with 0x02 in its dbc field. This causes
      ALSA Fireworks driver to detect discontinuity. In this case, firmware
      version 5.7.0, 5.7.3 and 5.8.0 are used.
      
      Payload  CIP      CIP
      quadlets header1  header2
      02       00050002 90ffffff <-
      42       0005000a 90013000
      42       00050012 90014400
      42       0005001a 90015800
      02       0005001a 90ffffff
      42       00050022 90019000
      42       0005002a 9001a400
      42       00050032 9001b800
      02       00050032 90ffffff
      42       0005003a 9001d000
      42       00050042 9001e400
      42       0005004a 9001f800
      02       0005004a 90ffffff
      (AudioFire2 with firmware version 5.7.)
      
      $ dmesg
      snd-fireworks fw1.0: Detect discontinuity of CIP: 00 02
      
      These models, AudioFire8 (since Jul 2009 ) and Gibson Robot Interface
      Pack series uses the same ARM binary as their firmware. Thus, this
      quirk may be observed among them.
      
      This commit adds a new member for AMDTP structure. This member represents
      the value of dbc field in a first AMDTP packet. Drivers can set it with
      a preferred value according to model's quirk.
      Tested-by: NJohannes Oertei <johannes.oertel@uni-due.de>
      Signed-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      18f5ed36
  7. 27 5月, 2015 1 次提交
    • T
      ALSA: firewire-lib: fix buffer-over-run when detecting packet discontinuity · 31ea49ba
      Takashi Sakamoto 提交于
      When detecting packet discontinuity, handle_in_packet() returns minus value
      and this value is assigned to unsigned int variable, then the variable has
      huge value. As a result, the variable causes buffer-over-run in
      handle_out_packet(). This brings invalid page request and system hangup.
      
      This commit fixes the bug to add a new argument into handle_in_packet()
      and the number of handled data blocks is assignd to it. The function
      return value is just used to check error.
      
      I also considered to change the type of local variable to 'int' in
      in_stream_callback(). This idea is based on type-conversion in C standard,
      while it may cause future problems when adding more works. Thus, I dropped
      this idea.
      
      Fixes: 6fc6b9ce('ALSA: firewire-lib: pass the number of data blocks in incoming packets to outgoing packets')
      Reported-by: NDan Carpenter <dan.carpenter@oracle.com>
      Signed-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      31ea49ba
  8. 24 5月, 2015 4 次提交
  9. 23 5月, 2015 5 次提交
  10. 10 3月, 2015 1 次提交
  11. 23 2月, 2015 2 次提交
  12. 17 1月, 2015 2 次提交
  13. 10 11月, 2014 1 次提交
    • T
      ALSA: pcm: Add snd_pcm_stop_xrun() helper · 1fb8510c
      Takashi Iwai 提交于
      Add a new helper function snd_pcm_stop_xrun() to the standard sequnce
      lock/snd_pcm_stop(XRUN)/unlock by a single call, and replace the
      existing open codes with this helper.
      
      The function checks the PCM running state to prevent setting the wrong
      state, too, for more safety.
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      1fb8510c
  14. 29 8月, 2014 1 次提交
    • T
      ALSA: firewire-lib/dice: add arrangements of PCM pointer and interrupts for Dice quirk · 65845f29
      Takashi Sakamoto 提交于
      In IEC 61883-6, one data block transfers one event. In ALSA, the event equals one PCM frame,
      hence one data block transfers one PCM frame. But Dice has a quirk at higher sampling rate
      (176.4/192.0 kHz) that one data block transfers two PCM frames.
      
      Commit 10550bea ("ALSA: dice/firewire-lib: Keep dualwire mode but obsolete
      CIP_HI_DUALWIRE") moved some codes related to this quirk into Dice driver. But the commit
      forgot to add arrangements for PCM period interrupts and DMA pointer updates. As a result, Dice
      driver cannot work correctly at higher sampling rate.
      
      This commit adds 'double_pcm_frames' parameter to amdtp structure for this quirk. When this
      parameter is set, PCM period interrupts and DMA pointer updates occur at double speed than in
      IEC 61883-6.
      Reported-by: NDaniel Robbins <drobbins@funtoo.org>
      Fixes: 10550bea ("ALSA: dice/firewire-lib: Keep dualwire mode but obsolete CIP_HI_DUALWIRE")
      Signed-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Cc: <stable@vger.kernel.org> # 3.16
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      65845f29
  15. 02 6月, 2014 1 次提交
    • T
      ALSA: firewire-lib: Use IEC 61883-6 compliant labels for Raw Audio data · a6975f2a
      Takashi Sakamoto 提交于
      According to AM824 in IEC 61883-6:2002, 2 bits in LSB of label for Raw Audio
      data means Valid Length Code (VBL). Ths value is:
      - b00 for 24 bits sample (label is 0x40)
      - b01 for 20 bits sample (label is 0x41)
      - b10 for 16 bits sample (label is 0x42)
      
      But current firewire-lib apply 24 bits label for both of 16/24 bits samples.
      
      As long as developers investigate BeBoB/Fireworks/OXFW/Dice, all of them
      have a behaviour to ignore the label. They can generate correct sound even
      if firewire-lib gives wrong label (i.e. 0xff). On BeBoB, this is not only
      for Raw Audio data channel, but also for IEC 60958 Conformant data channel.
      
      So there is little possibility of regression.
      Acked-by: NClemens Ladisch <clemens@ladisch.de>
      Signed-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      a6975f2a
  16. 27 5月, 2014 1 次提交
  17. 26 5月, 2014 2 次提交
    • T
      ALSA: bebob/firewire-lib: Add a quirk of wrong dbc in empty packet for M-Audio... · 9d59124c
      Takashi Sakamoto 提交于
      ALSA: bebob/firewire-lib: Add a quirk of wrong dbc in empty packet for M-Audio special Firewire series
      
      M-Audio Firewire 1814 has a quirk, ProjectMix I/O also has. They transmit
      empty packet with wrong value of dbc incremented by 8 at high sampling rate.
      According to IEC 61883-1, this value should be the same as the one in
      previous packet.
      
      This commit adds a flag named as CIP_EMPTY_HAS_WRONG_DBC. With flag, the value
      of dbc in empty packet is overwittern by an expected value.
      
      This is an example of this quirk:
      CIP Header 0	CIP Header 1	Payload size
      010D0000	9004F759	210
      010D0010	90040B59	210
      010D0020	90042359	210
      01020028	9004FFFF	2  <-
      010D0030	90043759	210
      010D0040	90044B59	210
      010D0050	90046359	210
      01020058	9004FFFF	2  <-
      010D0060	90047759	210
      010D0070	90048B59	210
      010D0080	9004A359	210
      01020088	9004FFFF	2  <-
      010D0090	9004B759	210
      010D00A0	9004CB59	210
      010D00B0	9004E359	210
      010200B8	9004FFFF	2  <-
      010D00C0	9004F759	210
      010D00D0	90040B59	210
      010D00E0	90042359	210
      Signed-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      9d59124c
    • T
      ALSA: bebob/firewire-lib: Add a quirk for discontinuity at bus reset · b6bc8123
      Takashi Sakamoto 提交于
      Normal BeBoB firmware has a quirk. When receiving bus reset, it transmits
      packets with discontinuous value in dbc field.
      
      This causes two situation, one is to abort streaming by firewire-lib as a
      result of detecting the discontinuity. Another is to call driver's .update()
      because of bus reset. These two is generated independently. (The former
      depends on isochronous stream and the latter depends on IEEE1394 bus driver.)
      
      When BeBoB driver works with XRUN-recoverable applications, this situation
      looks like stream_start_duplex() call followed by stream_update_duplex() call
      because applications will call snd_pcm_prepare() immediately at XRUN.
      
      To update connections and streams at first, this commit use completion. When
      queueing error occurs, stream_start_duplex() is forced to wait maximum
      1000msec. During this, when .update() is called, the completion is waken and
      stream_start_duplex() is processed without breaking connections.
      
      At bus reset, stream_start_duplex() shouldn't break/establish connections and
      stream_update_duplex() should update connections because a caller of
      fw_iso_resources_allocate() is responsible for calling
      fw_iso_resources_update() on bus reset.
      
      This commit also adds a flag, which has an effect to skip checking continuity
      for first packet. This flag is useful for BeBoB quirk to start handling packets
      during streaming.
      Signed-off-by: NTakashi Sakamoto <o-takashi@sakamocchi.jp>
      Signed-off-by: NTakashi Iwai <tiwai@suse.de>
      b6bc8123