lin
2025-04-23 399353eb5dc7e9c1db94cc97c380dc7f66c51a4c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#ifndef SOUND_FIREWIRE_LIB_H_INCLUDED
#define SOUND_FIREWIRE_LIB_H_INCLUDED
 
#include <linux/firewire-constants.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <sound/rawmidi.h>
 
struct fw_unit;
 
#define FW_GENERATION_MASK    0x00ff
#define FW_FIXED_GENERATION    0x0100
#define FW_QUIET        0x0200
 
int snd_fw_transaction(struct fw_unit *unit, int tcode,
              u64 offset, void *buffer, size_t length,
              unsigned int flags);
 
/* returns true if retrying the transaction would not make sense */
static inline bool rcode_is_permanent_error(int rcode)
{
   return rcode == RCODE_TYPE_ERROR || rcode == RCODE_ADDRESS_ERROR;
}
 
void snd_fw_schedule_registration(struct fw_unit *unit,
                 struct delayed_work *dwork);
 
struct snd_fw_async_midi_port;
typedef int (*snd_fw_async_midi_port_fill)(
               struct snd_rawmidi_substream *substream,
               u8 *buf);
 
struct snd_fw_async_midi_port {
   struct fw_device *parent;
   struct work_struct work;
   bool idling;
   ktime_t next_ktime;
   bool error;
 
   u64 addr;
   struct fw_transaction transaction;
 
   u8 *buf;
   unsigned int len;
 
   struct snd_rawmidi_substream *substream;
   snd_fw_async_midi_port_fill fill;
   int consume_bytes;
};
 
int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
       struct fw_unit *unit, u64 addr, unsigned int len,
       snd_fw_async_midi_port_fill fill);
void snd_fw_async_midi_port_destroy(struct snd_fw_async_midi_port *port);
 
/**
 * snd_fw_async_midi_port_run - run transactions for the async MIDI port
 * @port: the asynchronous MIDI port
 * @substream: the MIDI substream
 */
static inline void
snd_fw_async_midi_port_run(struct snd_fw_async_midi_port *port,
              struct snd_rawmidi_substream *substream)
{
   if (!port->error) {
       port->substream = substream;
       schedule_work(&port->work);
   }
}
 
/**
 * snd_fw_async_midi_port_finish - finish the asynchronous MIDI port
 * @port: the asynchronous MIDI port
 */
static inline void
snd_fw_async_midi_port_finish(struct snd_fw_async_midi_port *port)
{
   port->substream = NULL;
   port->error = false;
}
 
#endif