xref: /openbmc/linux/sound/usb/midi2.c (revision 278002edb19bce2c628fafb0af936e77000f3a5b)
1ff49d1dfSTakashi Iwai // SPDX-License-Identifier: GPL-2.0-or-later
2ff49d1dfSTakashi Iwai /*
3ff49d1dfSTakashi Iwai  * MIDI 2.0 support
4ff49d1dfSTakashi Iwai  */
5ff49d1dfSTakashi Iwai 
6ff49d1dfSTakashi Iwai #include <linux/bitops.h>
7ff49d1dfSTakashi Iwai #include <linux/string.h>
8ff49d1dfSTakashi Iwai #include <linux/init.h>
9ff49d1dfSTakashi Iwai #include <linux/slab.h>
10ff49d1dfSTakashi Iwai #include <linux/usb.h>
11ff49d1dfSTakashi Iwai #include <linux/wait.h>
12ff49d1dfSTakashi Iwai #include <linux/module.h>
13ff49d1dfSTakashi Iwai #include <linux/moduleparam.h>
14ff49d1dfSTakashi Iwai #include <linux/usb/audio.h>
15ff49d1dfSTakashi Iwai #include <linux/usb/midi.h>
16ff49d1dfSTakashi Iwai #include <linux/usb/midi-v2.h>
17ff49d1dfSTakashi Iwai 
18ff49d1dfSTakashi Iwai #include <sound/core.h>
19ff49d1dfSTakashi Iwai #include <sound/control.h>
20ff49d1dfSTakashi Iwai #include <sound/ump.h>
21ff49d1dfSTakashi Iwai #include "usbaudio.h"
22ff49d1dfSTakashi Iwai #include "midi.h"
23ff49d1dfSTakashi Iwai #include "midi2.h"
24ff49d1dfSTakashi Iwai #include "helper.h"
25ff49d1dfSTakashi Iwai 
26ff49d1dfSTakashi Iwai static bool midi2_enable = true;
27ff49d1dfSTakashi Iwai module_param(midi2_enable, bool, 0444);
28ff49d1dfSTakashi Iwai MODULE_PARM_DESC(midi2_enable, "Enable MIDI 2.0 support.");
29ff49d1dfSTakashi Iwai 
30960a1149STakashi Iwai static bool midi2_ump_probe = true;
31960a1149STakashi Iwai module_param(midi2_ump_probe, bool, 0444);
32960a1149STakashi Iwai MODULE_PARM_DESC(midi2_ump_probe, "Probe UMP v1.1 support at first.");
33960a1149STakashi Iwai 
34ff49d1dfSTakashi Iwai /* stream direction; just shorter names */
35ff49d1dfSTakashi Iwai enum {
36ff49d1dfSTakashi Iwai 	STR_OUT = SNDRV_RAWMIDI_STREAM_OUTPUT,
37ff49d1dfSTakashi Iwai 	STR_IN = SNDRV_RAWMIDI_STREAM_INPUT
38ff49d1dfSTakashi Iwai };
39ff49d1dfSTakashi Iwai 
40ff49d1dfSTakashi Iwai #define NUM_URBS	8
41ff49d1dfSTakashi Iwai 
42ff49d1dfSTakashi Iwai struct snd_usb_midi2_urb;
43ff49d1dfSTakashi Iwai struct snd_usb_midi2_endpoint;
44ff49d1dfSTakashi Iwai struct snd_usb_midi2_ump;
45ff49d1dfSTakashi Iwai struct snd_usb_midi2_interface;
46ff49d1dfSTakashi Iwai 
47ff49d1dfSTakashi Iwai /* URB context */
48ff49d1dfSTakashi Iwai struct snd_usb_midi2_urb {
49ff49d1dfSTakashi Iwai 	struct urb *urb;
50ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep;
51ff49d1dfSTakashi Iwai 	unsigned int index;		/* array index */
52ff49d1dfSTakashi Iwai };
53ff49d1dfSTakashi Iwai 
54ff49d1dfSTakashi Iwai /* A USB MIDI input/output endpoint */
55ff49d1dfSTakashi Iwai struct snd_usb_midi2_endpoint {
56ff49d1dfSTakashi Iwai 	struct usb_device *dev;
57ff49d1dfSTakashi Iwai 	const struct usb_ms20_endpoint_descriptor *ms_ep; /* reference to EP descriptor */
58ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *pair;	/* bidirectional pair EP */
596b41e64aSTakashi Iwai 	struct snd_usb_midi2_ump *rmidi;	/* assigned UMP EP pair */
606b41e64aSTakashi Iwai 	struct snd_ump_endpoint *ump;		/* assigned UMP EP */
61ff49d1dfSTakashi Iwai 	int direction;			/* direction (STR_IN/OUT) */
62ff49d1dfSTakashi Iwai 	unsigned int endpoint;		/* EP number */
63ff49d1dfSTakashi Iwai 	unsigned int pipe;		/* URB pipe */
64ff49d1dfSTakashi Iwai 	unsigned int packets;		/* packet buffer size in bytes */
65ff49d1dfSTakashi Iwai 	unsigned int interval;		/* interval for INT EP */
66ff49d1dfSTakashi Iwai 	wait_queue_head_t wait;		/* URB waiter */
67ff49d1dfSTakashi Iwai 	spinlock_t lock;		/* URB locking */
68ff49d1dfSTakashi Iwai 	struct snd_rawmidi_substream *substream; /* NULL when closed */
69ff49d1dfSTakashi Iwai 	unsigned int num_urbs;		/* number of allocated URBs */
70ff49d1dfSTakashi Iwai 	unsigned long urb_free;		/* bitmap for free URBs */
71ff49d1dfSTakashi Iwai 	unsigned long urb_free_mask;	/* bitmask for free URBs */
72ff49d1dfSTakashi Iwai 	atomic_t running;		/* running status */
73ff49d1dfSTakashi Iwai 	atomic_t suspended;		/* saved running status for suspend */
74ff49d1dfSTakashi Iwai 	bool disconnected;		/* shadow of umidi->disconnected */
75ff49d1dfSTakashi Iwai 	struct list_head list;		/* list to umidi->ep_list */
76ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_urb urbs[NUM_URBS];
77ff49d1dfSTakashi Iwai };
78ff49d1dfSTakashi Iwai 
79ff49d1dfSTakashi Iwai /* A UMP endpoint - one or two USB MIDI endpoints are assigned */
80ff49d1dfSTakashi Iwai struct snd_usb_midi2_ump {
81ff49d1dfSTakashi Iwai 	struct usb_device *dev;
82ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_interface *umidi;	/* reference to MIDI iface */
83ff49d1dfSTakashi Iwai 	struct snd_ump_endpoint *ump;		/* assigned UMP EP object */
84ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *eps[2];	/* USB MIDI endpoints */
85ff49d1dfSTakashi Iwai 	int index;				/* rawmidi device index */
86ff49d1dfSTakashi Iwai 	unsigned char usb_block_id;		/* USB GTB id used for finding a pair */
8754852e8fSTakashi Iwai 	bool ump_parsed;			/* Parsed UMP 1.1 EP/FB info*/
88ff49d1dfSTakashi Iwai 	struct list_head list;		/* list to umidi->rawmidi_list */
89ff49d1dfSTakashi Iwai };
90ff49d1dfSTakashi Iwai 
91ff49d1dfSTakashi Iwai /* top-level instance per USB MIDI interface */
92ff49d1dfSTakashi Iwai struct snd_usb_midi2_interface {
93ff49d1dfSTakashi Iwai 	struct snd_usb_audio *chip;	/* assigned USB-audio card */
94ff49d1dfSTakashi Iwai 	struct usb_interface *iface;	/* assigned USB interface */
95ff49d1dfSTakashi Iwai 	struct usb_host_interface *hostif;
96ff49d1dfSTakashi Iwai 	const char *blk_descs;		/* group terminal block descriptors */
97ff49d1dfSTakashi Iwai 	unsigned int blk_desc_size;	/* size of GTB descriptors */
98ff49d1dfSTakashi Iwai 	bool disconnected;
99ff49d1dfSTakashi Iwai 	struct list_head ep_list;	/* list of endpoints */
100ff49d1dfSTakashi Iwai 	struct list_head rawmidi_list;	/* list of UMP rawmidis */
101ff49d1dfSTakashi Iwai 	struct list_head list;		/* list to chip->midi_v2_list */
102ff49d1dfSTakashi Iwai };
103ff49d1dfSTakashi Iwai 
104ff49d1dfSTakashi Iwai /* submit URBs as much as possible; used for both input and output */
do_submit_urbs_locked(struct snd_usb_midi2_endpoint * ep,int (* prepare)(struct snd_usb_midi2_endpoint *,struct urb *))105ff49d1dfSTakashi Iwai static void do_submit_urbs_locked(struct snd_usb_midi2_endpoint *ep,
106ff49d1dfSTakashi Iwai 				  int (*prepare)(struct snd_usb_midi2_endpoint *,
107ff49d1dfSTakashi Iwai 						 struct urb *))
108ff49d1dfSTakashi Iwai {
109ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_urb *ctx;
110ff49d1dfSTakashi Iwai 	int index, err = 0;
111ff49d1dfSTakashi Iwai 
112ff49d1dfSTakashi Iwai 	if (ep->disconnected)
113ff49d1dfSTakashi Iwai 		return;
114ff49d1dfSTakashi Iwai 
115ff49d1dfSTakashi Iwai 	while (ep->urb_free) {
116ff49d1dfSTakashi Iwai 		index = find_first_bit(&ep->urb_free, ep->num_urbs);
117ff49d1dfSTakashi Iwai 		if (index >= ep->num_urbs)
118ff49d1dfSTakashi Iwai 			return;
119ff49d1dfSTakashi Iwai 		ctx = &ep->urbs[index];
120ff49d1dfSTakashi Iwai 		err = prepare(ep, ctx->urb);
121ff49d1dfSTakashi Iwai 		if (err < 0)
122ff49d1dfSTakashi Iwai 			return;
123ff49d1dfSTakashi Iwai 		if (!ctx->urb->transfer_buffer_length)
124ff49d1dfSTakashi Iwai 			return;
125ff49d1dfSTakashi Iwai 		ctx->urb->dev = ep->dev;
126ff49d1dfSTakashi Iwai 		err = usb_submit_urb(ctx->urb, GFP_ATOMIC);
127ff49d1dfSTakashi Iwai 		if (err < 0) {
128ff49d1dfSTakashi Iwai 			dev_dbg(&ep->dev->dev,
129ff49d1dfSTakashi Iwai 				"usb_submit_urb error %d\n", err);
130ff49d1dfSTakashi Iwai 			return;
131ff49d1dfSTakashi Iwai 		}
132ff49d1dfSTakashi Iwai 		clear_bit(index, &ep->urb_free);
133ff49d1dfSTakashi Iwai 	}
134ff49d1dfSTakashi Iwai }
135ff49d1dfSTakashi Iwai 
136ff49d1dfSTakashi Iwai /* prepare for output submission: copy from rawmidi buffer to urb packet */
prepare_output_urb(struct snd_usb_midi2_endpoint * ep,struct urb * urb)137ff49d1dfSTakashi Iwai static int prepare_output_urb(struct snd_usb_midi2_endpoint *ep,
138ff49d1dfSTakashi Iwai 			      struct urb *urb)
139ff49d1dfSTakashi Iwai {
140ff49d1dfSTakashi Iwai 	int count;
141ff49d1dfSTakashi Iwai 
1426b41e64aSTakashi Iwai 	count = snd_ump_transmit(ep->ump, urb->transfer_buffer,
143ff49d1dfSTakashi Iwai 				 ep->packets);
144ff49d1dfSTakashi Iwai 	if (count < 0) {
145ff49d1dfSTakashi Iwai 		dev_dbg(&ep->dev->dev, "rawmidi transmit error %d\n", count);
146ff49d1dfSTakashi Iwai 		return count;
147ff49d1dfSTakashi Iwai 	}
148ff49d1dfSTakashi Iwai 	cpu_to_le32_array((u32 *)urb->transfer_buffer, count >> 2);
149ff49d1dfSTakashi Iwai 	urb->transfer_buffer_length = count;
150ff49d1dfSTakashi Iwai 	return 0;
151ff49d1dfSTakashi Iwai }
152ff49d1dfSTakashi Iwai 
submit_output_urbs_locked(struct snd_usb_midi2_endpoint * ep)153ff49d1dfSTakashi Iwai static void submit_output_urbs_locked(struct snd_usb_midi2_endpoint *ep)
154ff49d1dfSTakashi Iwai {
155ff49d1dfSTakashi Iwai 	do_submit_urbs_locked(ep, prepare_output_urb);
156ff49d1dfSTakashi Iwai }
157ff49d1dfSTakashi Iwai 
158ff49d1dfSTakashi Iwai /* URB completion for output; re-filling and re-submit */
output_urb_complete(struct urb * urb)159ff49d1dfSTakashi Iwai static void output_urb_complete(struct urb *urb)
160ff49d1dfSTakashi Iwai {
161ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_urb *ctx = urb->context;
162ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep = ctx->ep;
163ff49d1dfSTakashi Iwai 	unsigned long flags;
164ff49d1dfSTakashi Iwai 
165ff49d1dfSTakashi Iwai 	spin_lock_irqsave(&ep->lock, flags);
166ff49d1dfSTakashi Iwai 	set_bit(ctx->index, &ep->urb_free);
167ff49d1dfSTakashi Iwai 	if (urb->status >= 0 && atomic_read(&ep->running))
168ff49d1dfSTakashi Iwai 		submit_output_urbs_locked(ep);
169ff49d1dfSTakashi Iwai 	if (ep->urb_free == ep->urb_free_mask)
170ff49d1dfSTakashi Iwai 		wake_up(&ep->wait);
171ff49d1dfSTakashi Iwai 	spin_unlock_irqrestore(&ep->lock, flags);
172ff49d1dfSTakashi Iwai }
173ff49d1dfSTakashi Iwai 
174ff49d1dfSTakashi Iwai /* prepare for input submission: just set the buffer length */
prepare_input_urb(struct snd_usb_midi2_endpoint * ep,struct urb * urb)175ff49d1dfSTakashi Iwai static int prepare_input_urb(struct snd_usb_midi2_endpoint *ep,
176ff49d1dfSTakashi Iwai 			     struct urb *urb)
177ff49d1dfSTakashi Iwai {
178ff49d1dfSTakashi Iwai 	urb->transfer_buffer_length = ep->packets;
179ff49d1dfSTakashi Iwai 	return 0;
180ff49d1dfSTakashi Iwai }
181ff49d1dfSTakashi Iwai 
submit_input_urbs_locked(struct snd_usb_midi2_endpoint * ep)182ff49d1dfSTakashi Iwai static void submit_input_urbs_locked(struct snd_usb_midi2_endpoint *ep)
183ff49d1dfSTakashi Iwai {
184ff49d1dfSTakashi Iwai 	do_submit_urbs_locked(ep, prepare_input_urb);
185ff49d1dfSTakashi Iwai }
186ff49d1dfSTakashi Iwai 
187ff49d1dfSTakashi Iwai /* URB completion for input; copy into rawmidi buffer and resubmit */
input_urb_complete(struct urb * urb)188ff49d1dfSTakashi Iwai static void input_urb_complete(struct urb *urb)
189ff49d1dfSTakashi Iwai {
190ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_urb *ctx = urb->context;
191ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep = ctx->ep;
192ff49d1dfSTakashi Iwai 	unsigned long flags;
193ff49d1dfSTakashi Iwai 	int len;
194ff49d1dfSTakashi Iwai 
195ff49d1dfSTakashi Iwai 	spin_lock_irqsave(&ep->lock, flags);
196ff49d1dfSTakashi Iwai 	if (ep->disconnected || urb->status < 0)
197ff49d1dfSTakashi Iwai 		goto dequeue;
198ff49d1dfSTakashi Iwai 	len = urb->actual_length;
199ff49d1dfSTakashi Iwai 	len &= ~3; /* align UMP */
200ff49d1dfSTakashi Iwai 	if (len > ep->packets)
201ff49d1dfSTakashi Iwai 		len = ep->packets;
2026b41e64aSTakashi Iwai 	if (len > 0) {
203ff49d1dfSTakashi Iwai 		le32_to_cpu_array((u32 *)urb->transfer_buffer, len >> 2);
2046b41e64aSTakashi Iwai 		snd_ump_receive(ep->ump, (u32 *)urb->transfer_buffer, len);
205ff49d1dfSTakashi Iwai 	}
206ff49d1dfSTakashi Iwai  dequeue:
207ff49d1dfSTakashi Iwai 	set_bit(ctx->index, &ep->urb_free);
208ff49d1dfSTakashi Iwai 	submit_input_urbs_locked(ep);
209ff49d1dfSTakashi Iwai 	if (ep->urb_free == ep->urb_free_mask)
210ff49d1dfSTakashi Iwai 		wake_up(&ep->wait);
211ff49d1dfSTakashi Iwai 	spin_unlock_irqrestore(&ep->lock, flags);
212ff49d1dfSTakashi Iwai }
213ff49d1dfSTakashi Iwai 
214ff49d1dfSTakashi Iwai /* URB submission helper; for both direction */
submit_io_urbs(struct snd_usb_midi2_endpoint * ep)215ff49d1dfSTakashi Iwai static void submit_io_urbs(struct snd_usb_midi2_endpoint *ep)
216ff49d1dfSTakashi Iwai {
217ff49d1dfSTakashi Iwai 	unsigned long flags;
218ff49d1dfSTakashi Iwai 
219ff49d1dfSTakashi Iwai 	if (!ep)
220ff49d1dfSTakashi Iwai 		return;
221ff49d1dfSTakashi Iwai 	spin_lock_irqsave(&ep->lock, flags);
222ff49d1dfSTakashi Iwai 	if (ep->direction == STR_IN)
223ff49d1dfSTakashi Iwai 		submit_input_urbs_locked(ep);
224ff49d1dfSTakashi Iwai 	else
225ff49d1dfSTakashi Iwai 		submit_output_urbs_locked(ep);
226ff49d1dfSTakashi Iwai 	spin_unlock_irqrestore(&ep->lock, flags);
227ff49d1dfSTakashi Iwai }
228ff49d1dfSTakashi Iwai 
229ff49d1dfSTakashi Iwai /* kill URBs for close, suspend and disconnect */
kill_midi_urbs(struct snd_usb_midi2_endpoint * ep,bool suspending)230ff49d1dfSTakashi Iwai static void kill_midi_urbs(struct snd_usb_midi2_endpoint *ep, bool suspending)
231ff49d1dfSTakashi Iwai {
232ff49d1dfSTakashi Iwai 	int i;
233ff49d1dfSTakashi Iwai 
234ff49d1dfSTakashi Iwai 	if (!ep)
235ff49d1dfSTakashi Iwai 		return;
236ff49d1dfSTakashi Iwai 	if (suspending)
237ff49d1dfSTakashi Iwai 		ep->suspended = ep->running;
238ff49d1dfSTakashi Iwai 	atomic_set(&ep->running, 0);
239ff49d1dfSTakashi Iwai 	for (i = 0; i < ep->num_urbs; i++) {
240ff49d1dfSTakashi Iwai 		if (!ep->urbs[i].urb)
241ff49d1dfSTakashi Iwai 			break;
242ff49d1dfSTakashi Iwai 		usb_kill_urb(ep->urbs[i].urb);
243ff49d1dfSTakashi Iwai 	}
244ff49d1dfSTakashi Iwai }
245ff49d1dfSTakashi Iwai 
246ff49d1dfSTakashi Iwai /* wait until all URBs get freed */
drain_urb_queue(struct snd_usb_midi2_endpoint * ep)247ff49d1dfSTakashi Iwai static void drain_urb_queue(struct snd_usb_midi2_endpoint *ep)
248ff49d1dfSTakashi Iwai {
249ff49d1dfSTakashi Iwai 	if (!ep)
250ff49d1dfSTakashi Iwai 		return;
251ff49d1dfSTakashi Iwai 	spin_lock_irq(&ep->lock);
252ff49d1dfSTakashi Iwai 	atomic_set(&ep->running, 0);
253ff49d1dfSTakashi Iwai 	wait_event_lock_irq_timeout(ep->wait,
254ff49d1dfSTakashi Iwai 				    ep->disconnected ||
255ff49d1dfSTakashi Iwai 				    ep->urb_free == ep->urb_free_mask,
256ff49d1dfSTakashi Iwai 				    ep->lock, msecs_to_jiffies(500));
257ff49d1dfSTakashi Iwai 	spin_unlock_irq(&ep->lock);
258ff49d1dfSTakashi Iwai }
259ff49d1dfSTakashi Iwai 
260ff49d1dfSTakashi Iwai /* release URBs for an EP */
free_midi_urbs(struct snd_usb_midi2_endpoint * ep)261ff49d1dfSTakashi Iwai static void free_midi_urbs(struct snd_usb_midi2_endpoint *ep)
262ff49d1dfSTakashi Iwai {
263ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_urb *ctx;
264ff49d1dfSTakashi Iwai 	int i;
265ff49d1dfSTakashi Iwai 
266ff49d1dfSTakashi Iwai 	if (!ep)
267ff49d1dfSTakashi Iwai 		return;
268b1757fa3STakashi Iwai 	for (i = 0; i < NUM_URBS; ++i) {
269ff49d1dfSTakashi Iwai 		ctx = &ep->urbs[i];
270ff49d1dfSTakashi Iwai 		if (!ctx->urb)
271ff49d1dfSTakashi Iwai 			break;
272ff49d1dfSTakashi Iwai 		usb_free_coherent(ep->dev, ep->packets,
273ff49d1dfSTakashi Iwai 				  ctx->urb->transfer_buffer,
274ff49d1dfSTakashi Iwai 				  ctx->urb->transfer_dma);
275ff49d1dfSTakashi Iwai 		usb_free_urb(ctx->urb);
276ff49d1dfSTakashi Iwai 		ctx->urb = NULL;
277ff49d1dfSTakashi Iwai 	}
278ff49d1dfSTakashi Iwai 	ep->num_urbs = 0;
279ff49d1dfSTakashi Iwai }
280ff49d1dfSTakashi Iwai 
281ff49d1dfSTakashi Iwai /* allocate URBs for an EP */
282b1757fa3STakashi Iwai /* the callers should handle allocation errors via free_midi_urbs() */
alloc_midi_urbs(struct snd_usb_midi2_endpoint * ep)283ff49d1dfSTakashi Iwai static int alloc_midi_urbs(struct snd_usb_midi2_endpoint *ep)
284ff49d1dfSTakashi Iwai {
285ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_urb *ctx;
286ff49d1dfSTakashi Iwai 	void (*comp)(struct urb *urb);
287ff49d1dfSTakashi Iwai 	void *buffer;
288ff49d1dfSTakashi Iwai 	int i, err;
289ff49d1dfSTakashi Iwai 	int endpoint, len;
290ff49d1dfSTakashi Iwai 
291ff49d1dfSTakashi Iwai 	endpoint = ep->endpoint;
292ff49d1dfSTakashi Iwai 	len = ep->packets;
293ff49d1dfSTakashi Iwai 	if (ep->direction == STR_IN)
294ff49d1dfSTakashi Iwai 		comp = input_urb_complete;
295ff49d1dfSTakashi Iwai 	else
296ff49d1dfSTakashi Iwai 		comp = output_urb_complete;
297ff49d1dfSTakashi Iwai 
298ff49d1dfSTakashi Iwai 	ep->num_urbs = 0;
299ff49d1dfSTakashi Iwai 	ep->urb_free = ep->urb_free_mask = 0;
300ff49d1dfSTakashi Iwai 	for (i = 0; i < NUM_URBS; i++) {
301ff49d1dfSTakashi Iwai 		ctx = &ep->urbs[i];
302ff49d1dfSTakashi Iwai 		ctx->index = i;
303ff49d1dfSTakashi Iwai 		ctx->urb = usb_alloc_urb(0, GFP_KERNEL);
304ff49d1dfSTakashi Iwai 		if (!ctx->urb) {
305ff49d1dfSTakashi Iwai 			dev_err(&ep->dev->dev, "URB alloc failed\n");
306ff49d1dfSTakashi Iwai 			return -ENOMEM;
307ff49d1dfSTakashi Iwai 		}
308ff49d1dfSTakashi Iwai 		ctx->ep = ep;
309ff49d1dfSTakashi Iwai 		buffer = usb_alloc_coherent(ep->dev, len, GFP_KERNEL,
310ff49d1dfSTakashi Iwai 					    &ctx->urb->transfer_dma);
311ff49d1dfSTakashi Iwai 		if (!buffer) {
312ff49d1dfSTakashi Iwai 			dev_err(&ep->dev->dev,
313ff49d1dfSTakashi Iwai 				"URB buffer alloc failed (size %d)\n", len);
314ff49d1dfSTakashi Iwai 			return -ENOMEM;
315ff49d1dfSTakashi Iwai 		}
316ff49d1dfSTakashi Iwai 		if (ep->interval)
317ff49d1dfSTakashi Iwai 			usb_fill_int_urb(ctx->urb, ep->dev, ep->pipe,
318ff49d1dfSTakashi Iwai 					 buffer, len, comp, ctx, ep->interval);
319ff49d1dfSTakashi Iwai 		else
320ff49d1dfSTakashi Iwai 			usb_fill_bulk_urb(ctx->urb, ep->dev, ep->pipe,
321ff49d1dfSTakashi Iwai 					  buffer, len, comp, ctx);
322ff49d1dfSTakashi Iwai 		err = usb_urb_ep_type_check(ctx->urb);
323ff49d1dfSTakashi Iwai 		if (err < 0) {
324ff49d1dfSTakashi Iwai 			dev_err(&ep->dev->dev, "invalid MIDI EP %x\n",
325ff49d1dfSTakashi Iwai 				endpoint);
326ff49d1dfSTakashi Iwai 			return err;
327ff49d1dfSTakashi Iwai 		}
328ff49d1dfSTakashi Iwai 		ctx->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
329ff49d1dfSTakashi Iwai 		ep->num_urbs++;
330ff49d1dfSTakashi Iwai 	}
331ff49d1dfSTakashi Iwai 	ep->urb_free = ep->urb_free_mask = GENMASK(ep->num_urbs - 1, 0);
332ff49d1dfSTakashi Iwai 	return 0;
333ff49d1dfSTakashi Iwai }
334ff49d1dfSTakashi Iwai 
335ff49d1dfSTakashi Iwai static struct snd_usb_midi2_endpoint *
ump_to_endpoint(struct snd_ump_endpoint * ump,int dir)3366b41e64aSTakashi Iwai ump_to_endpoint(struct snd_ump_endpoint *ump, int dir)
337ff49d1dfSTakashi Iwai {
338ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_ump *rmidi = ump->private_data;
339ff49d1dfSTakashi Iwai 
3406b41e64aSTakashi Iwai 	return rmidi->eps[dir];
341ff49d1dfSTakashi Iwai }
342ff49d1dfSTakashi Iwai 
3436b41e64aSTakashi Iwai /* ump open callback */
snd_usb_midi_v2_open(struct snd_ump_endpoint * ump,int dir)3446b41e64aSTakashi Iwai static int snd_usb_midi_v2_open(struct snd_ump_endpoint *ump, int dir)
345ff49d1dfSTakashi Iwai {
3466b41e64aSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep = ump_to_endpoint(ump, dir);
347ff49d1dfSTakashi Iwai 	int err = 0;
348ff49d1dfSTakashi Iwai 
349ff49d1dfSTakashi Iwai 	if (!ep || !ep->endpoint)
350ff49d1dfSTakashi Iwai 		return -ENODEV;
351ff49d1dfSTakashi Iwai 	if (ep->disconnected)
352ff49d1dfSTakashi Iwai 		return -EIO;
353ff49d1dfSTakashi Iwai 	if (ep->direction == STR_OUT) {
354ff49d1dfSTakashi Iwai 		err = alloc_midi_urbs(ep);
355b1757fa3STakashi Iwai 		if (err) {
356b1757fa3STakashi Iwai 			free_midi_urbs(ep);
357ff49d1dfSTakashi Iwai 			return err;
358ff49d1dfSTakashi Iwai 		}
359b1757fa3STakashi Iwai 	}
360ff49d1dfSTakashi Iwai 	return 0;
361ff49d1dfSTakashi Iwai }
362ff49d1dfSTakashi Iwai 
3636b41e64aSTakashi Iwai /* ump close callback */
snd_usb_midi_v2_close(struct snd_ump_endpoint * ump,int dir)3646b41e64aSTakashi Iwai static void snd_usb_midi_v2_close(struct snd_ump_endpoint *ump, int dir)
365ff49d1dfSTakashi Iwai {
3666b41e64aSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep = ump_to_endpoint(ump, dir);
367ff49d1dfSTakashi Iwai 
368ff49d1dfSTakashi Iwai 	if (ep->direction == STR_OUT) {
369ff49d1dfSTakashi Iwai 		kill_midi_urbs(ep, false);
370ff49d1dfSTakashi Iwai 		drain_urb_queue(ep);
371ff49d1dfSTakashi Iwai 		free_midi_urbs(ep);
372ff49d1dfSTakashi Iwai 	}
373ff49d1dfSTakashi Iwai }
374ff49d1dfSTakashi Iwai 
3756b41e64aSTakashi Iwai /* ump trigger callback */
snd_usb_midi_v2_trigger(struct snd_ump_endpoint * ump,int dir,int up)3766b41e64aSTakashi Iwai static void snd_usb_midi_v2_trigger(struct snd_ump_endpoint *ump, int dir,
377ff49d1dfSTakashi Iwai 				    int up)
378ff49d1dfSTakashi Iwai {
3796b41e64aSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep = ump_to_endpoint(ump, dir);
380ff49d1dfSTakashi Iwai 
381ff49d1dfSTakashi Iwai 	atomic_set(&ep->running, up);
382ff49d1dfSTakashi Iwai 	if (up && ep->direction == STR_OUT && !ep->disconnected)
383ff49d1dfSTakashi Iwai 		submit_io_urbs(ep);
384ff49d1dfSTakashi Iwai }
385ff49d1dfSTakashi Iwai 
3866b41e64aSTakashi Iwai /* ump drain callback */
snd_usb_midi_v2_drain(struct snd_ump_endpoint * ump,int dir)3876b41e64aSTakashi Iwai static void snd_usb_midi_v2_drain(struct snd_ump_endpoint *ump, int dir)
388ff49d1dfSTakashi Iwai {
3896b41e64aSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep = ump_to_endpoint(ump, dir);
390ff49d1dfSTakashi Iwai 
391ff49d1dfSTakashi Iwai 	drain_urb_queue(ep);
392ff49d1dfSTakashi Iwai }
393ff49d1dfSTakashi Iwai 
394ff49d1dfSTakashi Iwai /* allocate and start all input streams */
start_input_streams(struct snd_usb_midi2_interface * umidi)395ff49d1dfSTakashi Iwai static int start_input_streams(struct snd_usb_midi2_interface *umidi)
396ff49d1dfSTakashi Iwai {
397ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep;
398ff49d1dfSTakashi Iwai 	int err;
399ff49d1dfSTakashi Iwai 
400ff49d1dfSTakashi Iwai 	list_for_each_entry(ep, &umidi->ep_list, list) {
401ff49d1dfSTakashi Iwai 		if (ep->direction == STR_IN) {
402ff49d1dfSTakashi Iwai 			err = alloc_midi_urbs(ep);
403ff49d1dfSTakashi Iwai 			if (err < 0)
404ff49d1dfSTakashi Iwai 				goto error;
405ff49d1dfSTakashi Iwai 		}
406ff49d1dfSTakashi Iwai 	}
407ff49d1dfSTakashi Iwai 
408ff49d1dfSTakashi Iwai 	list_for_each_entry(ep, &umidi->ep_list, list) {
409ff49d1dfSTakashi Iwai 		if (ep->direction == STR_IN)
410ff49d1dfSTakashi Iwai 			submit_io_urbs(ep);
411ff49d1dfSTakashi Iwai 	}
412ff49d1dfSTakashi Iwai 
413ff49d1dfSTakashi Iwai 	return 0;
414ff49d1dfSTakashi Iwai 
415ff49d1dfSTakashi Iwai  error:
416ff49d1dfSTakashi Iwai 	list_for_each_entry(ep, &umidi->ep_list, list) {
417ff49d1dfSTakashi Iwai 		if (ep->direction == STR_IN)
418ff49d1dfSTakashi Iwai 			free_midi_urbs(ep);
419ff49d1dfSTakashi Iwai 	}
420ff49d1dfSTakashi Iwai 
421ff49d1dfSTakashi Iwai 	return err;
422ff49d1dfSTakashi Iwai }
423ff49d1dfSTakashi Iwai 
4246b41e64aSTakashi Iwai static const struct snd_ump_ops snd_usb_midi_v2_ump_ops = {
425ff49d1dfSTakashi Iwai 	.open = snd_usb_midi_v2_open,
426ff49d1dfSTakashi Iwai 	.close = snd_usb_midi_v2_close,
427ff49d1dfSTakashi Iwai 	.trigger = snd_usb_midi_v2_trigger,
428ff49d1dfSTakashi Iwai 	.drain = snd_usb_midi_v2_drain,
429ff49d1dfSTakashi Iwai };
430ff49d1dfSTakashi Iwai 
431ff49d1dfSTakashi Iwai /* create a USB MIDI 2.0 endpoint object */
create_midi2_endpoint(struct snd_usb_midi2_interface * umidi,struct usb_host_endpoint * hostep,const struct usb_ms20_endpoint_descriptor * ms_ep)432ff49d1dfSTakashi Iwai static int create_midi2_endpoint(struct snd_usb_midi2_interface *umidi,
433ff49d1dfSTakashi Iwai 				 struct usb_host_endpoint *hostep,
434ff49d1dfSTakashi Iwai 				 const struct usb_ms20_endpoint_descriptor *ms_ep)
435ff49d1dfSTakashi Iwai {
436ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep;
437ff49d1dfSTakashi Iwai 	int endpoint, dir;
438ff49d1dfSTakashi Iwai 
439ff49d1dfSTakashi Iwai 	usb_audio_dbg(umidi->chip, "Creating an EP 0x%02x, #GTB=%d\n",
440ff49d1dfSTakashi Iwai 		      hostep->desc.bEndpointAddress,
441ff49d1dfSTakashi Iwai 		      ms_ep->bNumGrpTrmBlock);
442ff49d1dfSTakashi Iwai 
443ff49d1dfSTakashi Iwai 	ep = kzalloc(sizeof(*ep), GFP_KERNEL);
444ff49d1dfSTakashi Iwai 	if (!ep)
445ff49d1dfSTakashi Iwai 		return -ENOMEM;
446ff49d1dfSTakashi Iwai 
447ff49d1dfSTakashi Iwai 	spin_lock_init(&ep->lock);
448ff49d1dfSTakashi Iwai 	init_waitqueue_head(&ep->wait);
449ff49d1dfSTakashi Iwai 	ep->dev = umidi->chip->dev;
450ff49d1dfSTakashi Iwai 	endpoint = hostep->desc.bEndpointAddress;
451ff49d1dfSTakashi Iwai 	dir = (endpoint & USB_DIR_IN) ? STR_IN : STR_OUT;
452ff49d1dfSTakashi Iwai 
453ff49d1dfSTakashi Iwai 	ep->endpoint = endpoint;
454ff49d1dfSTakashi Iwai 	ep->direction = dir;
455ff49d1dfSTakashi Iwai 	ep->ms_ep = ms_ep;
456ff49d1dfSTakashi Iwai 	if (usb_endpoint_xfer_int(&hostep->desc))
457ff49d1dfSTakashi Iwai 		ep->interval = hostep->desc.bInterval;
458ff49d1dfSTakashi Iwai 	else
459ff49d1dfSTakashi Iwai 		ep->interval = 0;
460ff49d1dfSTakashi Iwai 	if (dir == STR_IN) {
461ff49d1dfSTakashi Iwai 		if (ep->interval)
462ff49d1dfSTakashi Iwai 			ep->pipe = usb_rcvintpipe(ep->dev, endpoint);
463ff49d1dfSTakashi Iwai 		else
464ff49d1dfSTakashi Iwai 			ep->pipe = usb_rcvbulkpipe(ep->dev, endpoint);
465ff49d1dfSTakashi Iwai 	} else {
466ff49d1dfSTakashi Iwai 		if (ep->interval)
467ff49d1dfSTakashi Iwai 			ep->pipe = usb_sndintpipe(ep->dev, endpoint);
468ff49d1dfSTakashi Iwai 		else
469ff49d1dfSTakashi Iwai 			ep->pipe = usb_sndbulkpipe(ep->dev, endpoint);
470ff49d1dfSTakashi Iwai 	}
471ff49d1dfSTakashi Iwai 	ep->packets = usb_maxpacket(ep->dev, ep->pipe);
472ff49d1dfSTakashi Iwai 	list_add_tail(&ep->list, &umidi->ep_list);
473ff49d1dfSTakashi Iwai 
474ff49d1dfSTakashi Iwai 	return 0;
475ff49d1dfSTakashi Iwai }
476ff49d1dfSTakashi Iwai 
477ff49d1dfSTakashi Iwai /* destructor for endpoint; from snd_usb_midi_v2_free() */
free_midi2_endpoint(struct snd_usb_midi2_endpoint * ep)478ff49d1dfSTakashi Iwai static void free_midi2_endpoint(struct snd_usb_midi2_endpoint *ep)
479ff49d1dfSTakashi Iwai {
480ff49d1dfSTakashi Iwai 	list_del(&ep->list);
481ff49d1dfSTakashi Iwai 	free_midi_urbs(ep);
482ff49d1dfSTakashi Iwai 	kfree(ep);
483ff49d1dfSTakashi Iwai }
484ff49d1dfSTakashi Iwai 
485ff49d1dfSTakashi Iwai /* call all endpoint destructors */
free_all_midi2_endpoints(struct snd_usb_midi2_interface * umidi)486ff49d1dfSTakashi Iwai static void free_all_midi2_endpoints(struct snd_usb_midi2_interface *umidi)
487ff49d1dfSTakashi Iwai {
488ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep;
489ff49d1dfSTakashi Iwai 
490ff49d1dfSTakashi Iwai 	while (!list_empty(&umidi->ep_list)) {
491ff49d1dfSTakashi Iwai 		ep = list_first_entry(&umidi->ep_list,
492ff49d1dfSTakashi Iwai 				      struct snd_usb_midi2_endpoint, list);
493ff49d1dfSTakashi Iwai 		free_midi2_endpoint(ep);
494ff49d1dfSTakashi Iwai 	}
495ff49d1dfSTakashi Iwai }
496ff49d1dfSTakashi Iwai 
497ff49d1dfSTakashi Iwai /* find a MIDI STREAMING descriptor with a given subtype */
find_usb_ms_endpoint_descriptor(struct usb_host_endpoint * hostep,unsigned char subtype)498ff49d1dfSTakashi Iwai static void *find_usb_ms_endpoint_descriptor(struct usb_host_endpoint *hostep,
499ff49d1dfSTakashi Iwai 					     unsigned char subtype)
500ff49d1dfSTakashi Iwai {
501ff49d1dfSTakashi Iwai 	unsigned char *extra = hostep->extra;
502ff49d1dfSTakashi Iwai 	int extralen = hostep->extralen;
503ff49d1dfSTakashi Iwai 
504ff49d1dfSTakashi Iwai 	while (extralen > 3) {
505ff49d1dfSTakashi Iwai 		struct usb_ms_endpoint_descriptor *ms_ep =
506ff49d1dfSTakashi Iwai 			(struct usb_ms_endpoint_descriptor *)extra;
507ff49d1dfSTakashi Iwai 
508ff49d1dfSTakashi Iwai 		if (ms_ep->bLength > 3 &&
509ff49d1dfSTakashi Iwai 		    ms_ep->bDescriptorType == USB_DT_CS_ENDPOINT &&
510ff49d1dfSTakashi Iwai 		    ms_ep->bDescriptorSubtype == subtype)
511ff49d1dfSTakashi Iwai 			return ms_ep;
512ff49d1dfSTakashi Iwai 		if (!extra[0])
513ff49d1dfSTakashi Iwai 			break;
514ff49d1dfSTakashi Iwai 		extralen -= extra[0];
515ff49d1dfSTakashi Iwai 		extra += extra[0];
516ff49d1dfSTakashi Iwai 	}
517ff49d1dfSTakashi Iwai 	return NULL;
518ff49d1dfSTakashi Iwai }
519ff49d1dfSTakashi Iwai 
520ff49d1dfSTakashi Iwai /* get the full group terminal block descriptors and return the size */
get_group_terminal_block_descs(struct snd_usb_midi2_interface * umidi)521ff49d1dfSTakashi Iwai static int get_group_terminal_block_descs(struct snd_usb_midi2_interface *umidi)
522ff49d1dfSTakashi Iwai {
523ff49d1dfSTakashi Iwai 	struct usb_host_interface *hostif = umidi->hostif;
524ff49d1dfSTakashi Iwai 	struct usb_device *dev = umidi->chip->dev;
525ff49d1dfSTakashi Iwai 	struct usb_ms20_gr_trm_block_header_descriptor header = { 0 };
526ff49d1dfSTakashi Iwai 	unsigned char *data;
527ff49d1dfSTakashi Iwai 	int err, size;
528ff49d1dfSTakashi Iwai 
529ff49d1dfSTakashi Iwai 	err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
530ff49d1dfSTakashi Iwai 			      USB_REQ_GET_DESCRIPTOR,
531ff49d1dfSTakashi Iwai 			      USB_RECIP_INTERFACE | USB_TYPE_STANDARD | USB_DIR_IN,
532ff49d1dfSTakashi Iwai 			      USB_DT_CS_GR_TRM_BLOCK << 8 | hostif->desc.bAlternateSetting,
533ff49d1dfSTakashi Iwai 			      hostif->desc.bInterfaceNumber,
534ff49d1dfSTakashi Iwai 			      &header, sizeof(header));
535ff49d1dfSTakashi Iwai 	if (err < 0)
536ff49d1dfSTakashi Iwai 		return err;
537ff49d1dfSTakashi Iwai 	size = __le16_to_cpu(header.wTotalLength);
538ff49d1dfSTakashi Iwai 	if (!size) {
539ff49d1dfSTakashi Iwai 		dev_err(&dev->dev, "Failed to get GTB descriptors for %d:%d\n",
540ff49d1dfSTakashi Iwai 			hostif->desc.bInterfaceNumber, hostif->desc.bAlternateSetting);
541ff49d1dfSTakashi Iwai 		return -EINVAL;
542ff49d1dfSTakashi Iwai 	}
543ff49d1dfSTakashi Iwai 
544ff49d1dfSTakashi Iwai 	data = kzalloc(size, GFP_KERNEL);
545ff49d1dfSTakashi Iwai 	if (!data)
546ff49d1dfSTakashi Iwai 		return -ENOMEM;
547ff49d1dfSTakashi Iwai 
548ff49d1dfSTakashi Iwai 	err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
549ff49d1dfSTakashi Iwai 			      USB_REQ_GET_DESCRIPTOR,
550ff49d1dfSTakashi Iwai 			      USB_RECIP_INTERFACE | USB_TYPE_STANDARD | USB_DIR_IN,
551ff49d1dfSTakashi Iwai 			      USB_DT_CS_GR_TRM_BLOCK << 8 | hostif->desc.bAlternateSetting,
552ff49d1dfSTakashi Iwai 			      hostif->desc.bInterfaceNumber, data, size);
553ff49d1dfSTakashi Iwai 	if (err < 0) {
554ff49d1dfSTakashi Iwai 		kfree(data);
555ff49d1dfSTakashi Iwai 		return err;
556ff49d1dfSTakashi Iwai 	}
557ff49d1dfSTakashi Iwai 
558ff49d1dfSTakashi Iwai 	umidi->blk_descs = data;
559ff49d1dfSTakashi Iwai 	umidi->blk_desc_size = size;
560ff49d1dfSTakashi Iwai 	return 0;
561ff49d1dfSTakashi Iwai }
562ff49d1dfSTakashi Iwai 
563ff49d1dfSTakashi Iwai /* find the corresponding group terminal block descriptor */
564ff49d1dfSTakashi Iwai static const struct usb_ms20_gr_trm_block_descriptor *
find_group_terminal_block(struct snd_usb_midi2_interface * umidi,int id)565ff49d1dfSTakashi Iwai find_group_terminal_block(struct snd_usb_midi2_interface *umidi, int id)
566ff49d1dfSTakashi Iwai {
567ff49d1dfSTakashi Iwai 	const unsigned char *data = umidi->blk_descs;
568ff49d1dfSTakashi Iwai 	int size = umidi->blk_desc_size;
569ff49d1dfSTakashi Iwai 	const struct usb_ms20_gr_trm_block_descriptor *desc;
570ff49d1dfSTakashi Iwai 
571ff49d1dfSTakashi Iwai 	size -= sizeof(struct usb_ms20_gr_trm_block_header_descriptor);
572ff49d1dfSTakashi Iwai 	data += sizeof(struct usb_ms20_gr_trm_block_header_descriptor);
573ff49d1dfSTakashi Iwai 	while (size > 0 && *data && *data <= size) {
574ff49d1dfSTakashi Iwai 		desc = (const struct usb_ms20_gr_trm_block_descriptor *)data;
575ff49d1dfSTakashi Iwai 		if (desc->bLength >= sizeof(*desc) &&
576ff49d1dfSTakashi Iwai 		    desc->bDescriptorType == USB_DT_CS_GR_TRM_BLOCK &&
577ff49d1dfSTakashi Iwai 		    desc->bDescriptorSubtype == USB_MS_GR_TRM_BLOCK &&
578ff49d1dfSTakashi Iwai 		    desc->bGrpTrmBlkID == id)
579ff49d1dfSTakashi Iwai 			return desc;
580ff49d1dfSTakashi Iwai 		size -= *data;
581ff49d1dfSTakashi Iwai 		data += *data;
582ff49d1dfSTakashi Iwai 	}
583ff49d1dfSTakashi Iwai 
584ff49d1dfSTakashi Iwai 	return NULL;
585ff49d1dfSTakashi Iwai }
586ff49d1dfSTakashi Iwai 
587ff49d1dfSTakashi Iwai /* fill up the information from GTB */
parse_group_terminal_block(struct snd_usb_midi2_ump * rmidi,const struct usb_ms20_gr_trm_block_descriptor * desc)588ff49d1dfSTakashi Iwai static int parse_group_terminal_block(struct snd_usb_midi2_ump *rmidi,
589ff49d1dfSTakashi Iwai 				      const struct usb_ms20_gr_trm_block_descriptor *desc)
590ff49d1dfSTakashi Iwai {
591ff49d1dfSTakashi Iwai 	struct snd_ump_endpoint *ump = rmidi->ump;
592f4487c42STakashi Iwai 	unsigned int protocol, protocol_caps;
593ff49d1dfSTakashi Iwai 
594ff49d1dfSTakashi Iwai 	/* set default protocol */
595ff49d1dfSTakashi Iwai 	switch (desc->bMIDIProtocol) {
596ff49d1dfSTakashi Iwai 	case USB_MS_MIDI_PROTO_1_0_64:
597ff49d1dfSTakashi Iwai 	case USB_MS_MIDI_PROTO_1_0_64_JRTS:
598ff49d1dfSTakashi Iwai 	case USB_MS_MIDI_PROTO_1_0_128:
599ff49d1dfSTakashi Iwai 	case USB_MS_MIDI_PROTO_1_0_128_JRTS:
600f4487c42STakashi Iwai 		protocol = SNDRV_UMP_EP_INFO_PROTO_MIDI1;
601ff49d1dfSTakashi Iwai 		break;
602ff49d1dfSTakashi Iwai 	case USB_MS_MIDI_PROTO_2_0:
603ff49d1dfSTakashi Iwai 	case USB_MS_MIDI_PROTO_2_0_JRTS:
604f4487c42STakashi Iwai 		protocol = SNDRV_UMP_EP_INFO_PROTO_MIDI2;
605ff49d1dfSTakashi Iwai 		break;
606f4487c42STakashi Iwai 	default:
607f4487c42STakashi Iwai 		return 0;
608ff49d1dfSTakashi Iwai 	}
609ff49d1dfSTakashi Iwai 
610f4487c42STakashi Iwai 	if (ump->info.protocol && ump->info.protocol != protocol)
611f4487c42STakashi Iwai 		usb_audio_info(rmidi->umidi->chip,
612f4487c42STakashi Iwai 			       "Overriding preferred MIDI protocol in GTB %d: %x -> %x\n",
613f4487c42STakashi Iwai 			       rmidi->usb_block_id, ump->info.protocol,
614f4487c42STakashi Iwai 			       protocol);
615f4487c42STakashi Iwai 	ump->info.protocol = protocol;
616f4487c42STakashi Iwai 
617f4487c42STakashi Iwai 	protocol_caps = protocol;
618ff49d1dfSTakashi Iwai 	switch (desc->bMIDIProtocol) {
619ff49d1dfSTakashi Iwai 	case USB_MS_MIDI_PROTO_1_0_64_JRTS:
620ff49d1dfSTakashi Iwai 	case USB_MS_MIDI_PROTO_1_0_128_JRTS:
621ff49d1dfSTakashi Iwai 	case USB_MS_MIDI_PROTO_2_0_JRTS:
622f4487c42STakashi Iwai 		protocol_caps |= SNDRV_UMP_EP_INFO_PROTO_JRTS_TX |
623ff49d1dfSTakashi Iwai 			SNDRV_UMP_EP_INFO_PROTO_JRTS_RX;
624ff49d1dfSTakashi Iwai 		break;
625ff49d1dfSTakashi Iwai 	}
626ff49d1dfSTakashi Iwai 
627f4487c42STakashi Iwai 	if (ump->info.protocol_caps && ump->info.protocol_caps != protocol_caps)
628f4487c42STakashi Iwai 		usb_audio_info(rmidi->umidi->chip,
629f4487c42STakashi Iwai 			       "Overriding MIDI protocol caps in GTB %d: %x -> %x\n",
630f4487c42STakashi Iwai 			       rmidi->usb_block_id, ump->info.protocol_caps,
631f4487c42STakashi Iwai 			       protocol_caps);
632f4487c42STakashi Iwai 	ump->info.protocol_caps = protocol_caps;
633f4487c42STakashi Iwai 
634ff49d1dfSTakashi Iwai 	return 0;
635ff49d1dfSTakashi Iwai }
636ff49d1dfSTakashi Iwai 
637ff49d1dfSTakashi Iwai /* allocate and parse for each assigned group terminal block */
parse_group_terminal_blocks(struct snd_usb_midi2_interface * umidi)638ff49d1dfSTakashi Iwai static int parse_group_terminal_blocks(struct snd_usb_midi2_interface *umidi)
639ff49d1dfSTakashi Iwai {
640ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_ump *rmidi;
641ff49d1dfSTakashi Iwai 	const struct usb_ms20_gr_trm_block_descriptor *desc;
642ff49d1dfSTakashi Iwai 	int err;
643ff49d1dfSTakashi Iwai 
644ff49d1dfSTakashi Iwai 	err = get_group_terminal_block_descs(umidi);
645ff49d1dfSTakashi Iwai 	if (err < 0)
646ff49d1dfSTakashi Iwai 		return err;
647ff49d1dfSTakashi Iwai 	if (!umidi->blk_descs)
648ff49d1dfSTakashi Iwai 		return 0;
649ff49d1dfSTakashi Iwai 
650ff49d1dfSTakashi Iwai 	list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {
651ff49d1dfSTakashi Iwai 		desc = find_group_terminal_block(umidi, rmidi->usb_block_id);
652ff49d1dfSTakashi Iwai 		if (!desc)
653ff49d1dfSTakashi Iwai 			continue;
654ff49d1dfSTakashi Iwai 		err = parse_group_terminal_block(rmidi, desc);
655ff49d1dfSTakashi Iwai 		if (err < 0)
656ff49d1dfSTakashi Iwai 			return err;
657ff49d1dfSTakashi Iwai 	}
658ff49d1dfSTakashi Iwai 
659ff49d1dfSTakashi Iwai 	return 0;
660ff49d1dfSTakashi Iwai }
661ff49d1dfSTakashi Iwai 
662ff49d1dfSTakashi Iwai /* parse endpoints included in the given interface and create objects */
parse_midi_2_0_endpoints(struct snd_usb_midi2_interface * umidi)663ff49d1dfSTakashi Iwai static int parse_midi_2_0_endpoints(struct snd_usb_midi2_interface *umidi)
664ff49d1dfSTakashi Iwai {
665ff49d1dfSTakashi Iwai 	struct usb_host_interface *hostif = umidi->hostif;
666ff49d1dfSTakashi Iwai 	struct usb_host_endpoint *hostep;
667ff49d1dfSTakashi Iwai 	struct usb_ms20_endpoint_descriptor *ms_ep;
668ff49d1dfSTakashi Iwai 	int i, err;
669ff49d1dfSTakashi Iwai 
670ff49d1dfSTakashi Iwai 	for (i = 0; i < hostif->desc.bNumEndpoints; i++) {
671ff49d1dfSTakashi Iwai 		hostep = &hostif->endpoint[i];
672ff49d1dfSTakashi Iwai 		if (!usb_endpoint_xfer_bulk(&hostep->desc) &&
673ff49d1dfSTakashi Iwai 		    !usb_endpoint_xfer_int(&hostep->desc))
674ff49d1dfSTakashi Iwai 			continue;
675ff49d1dfSTakashi Iwai 		ms_ep = find_usb_ms_endpoint_descriptor(hostep, USB_MS_GENERAL_2_0);
676ff49d1dfSTakashi Iwai 		if (!ms_ep)
677ff49d1dfSTakashi Iwai 			continue;
678ff49d1dfSTakashi Iwai 		if (ms_ep->bLength <= sizeof(*ms_ep))
679ff49d1dfSTakashi Iwai 			continue;
680ff49d1dfSTakashi Iwai 		if (!ms_ep->bNumGrpTrmBlock)
681ff49d1dfSTakashi Iwai 			continue;
682ff49d1dfSTakashi Iwai 		if (ms_ep->bLength < sizeof(*ms_ep) + ms_ep->bNumGrpTrmBlock)
683ff49d1dfSTakashi Iwai 			continue;
684ff49d1dfSTakashi Iwai 		err = create_midi2_endpoint(umidi, hostep, ms_ep);
685ff49d1dfSTakashi Iwai 		if (err < 0)
686ff49d1dfSTakashi Iwai 			return err;
687ff49d1dfSTakashi Iwai 	}
688ff49d1dfSTakashi Iwai 	return 0;
689ff49d1dfSTakashi Iwai }
690ff49d1dfSTakashi Iwai 
free_all_midi2_umps(struct snd_usb_midi2_interface * umidi)691ff49d1dfSTakashi Iwai static void free_all_midi2_umps(struct snd_usb_midi2_interface *umidi)
692ff49d1dfSTakashi Iwai {
693ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_ump *rmidi;
694ff49d1dfSTakashi Iwai 
695ff49d1dfSTakashi Iwai 	while (!list_empty(&umidi->rawmidi_list)) {
696ff49d1dfSTakashi Iwai 		rmidi = list_first_entry(&umidi->rawmidi_list,
697ff49d1dfSTakashi Iwai 					 struct snd_usb_midi2_ump, list);
698ff49d1dfSTakashi Iwai 		list_del(&rmidi->list);
699ff49d1dfSTakashi Iwai 		kfree(rmidi);
700ff49d1dfSTakashi Iwai 	}
701ff49d1dfSTakashi Iwai }
702ff49d1dfSTakashi Iwai 
create_midi2_ump(struct snd_usb_midi2_interface * umidi,struct snd_usb_midi2_endpoint * ep_in,struct snd_usb_midi2_endpoint * ep_out,int blk_id)703ff49d1dfSTakashi Iwai static int create_midi2_ump(struct snd_usb_midi2_interface *umidi,
704ff49d1dfSTakashi Iwai 			    struct snd_usb_midi2_endpoint *ep_in,
705ff49d1dfSTakashi Iwai 			    struct snd_usb_midi2_endpoint *ep_out,
706ff49d1dfSTakashi Iwai 			    int blk_id)
707ff49d1dfSTakashi Iwai {
708ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_ump *rmidi;
709ff49d1dfSTakashi Iwai 	struct snd_ump_endpoint *ump;
710ff49d1dfSTakashi Iwai 	int input, output;
711ff49d1dfSTakashi Iwai 	char idstr[16];
712ff49d1dfSTakashi Iwai 	int err;
713ff49d1dfSTakashi Iwai 
714ff49d1dfSTakashi Iwai 	rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
715ff49d1dfSTakashi Iwai 	if (!rmidi)
716ff49d1dfSTakashi Iwai 		return -ENOMEM;
717ff49d1dfSTakashi Iwai 	INIT_LIST_HEAD(&rmidi->list);
718ff49d1dfSTakashi Iwai 	rmidi->dev = umidi->chip->dev;
719ff49d1dfSTakashi Iwai 	rmidi->umidi = umidi;
720ff49d1dfSTakashi Iwai 	rmidi->usb_block_id = blk_id;
721ff49d1dfSTakashi Iwai 
722ff49d1dfSTakashi Iwai 	rmidi->index = umidi->chip->num_rawmidis;
723ff49d1dfSTakashi Iwai 	snprintf(idstr, sizeof(idstr), "UMP %d", rmidi->index);
724ff49d1dfSTakashi Iwai 	input = ep_in ? 1 : 0;
725ff49d1dfSTakashi Iwai 	output = ep_out ? 1 : 0;
726ff49d1dfSTakashi Iwai 	err = snd_ump_endpoint_new(umidi->chip->card, idstr, rmidi->index,
727ff49d1dfSTakashi Iwai 				   output, input, &ump);
728ff49d1dfSTakashi Iwai 	if (err < 0) {
729ff49d1dfSTakashi Iwai 		usb_audio_dbg(umidi->chip, "Failed to create a UMP object\n");
730ff49d1dfSTakashi Iwai 		kfree(rmidi);
731ff49d1dfSTakashi Iwai 		return err;
732ff49d1dfSTakashi Iwai 	}
733ff49d1dfSTakashi Iwai 
734ff49d1dfSTakashi Iwai 	rmidi->ump = ump;
735ff49d1dfSTakashi Iwai 	umidi->chip->num_rawmidis++;
736ff49d1dfSTakashi Iwai 
737ff49d1dfSTakashi Iwai 	ump->private_data = rmidi;
7386b41e64aSTakashi Iwai 	ump->ops = &snd_usb_midi_v2_ump_ops;
739ff49d1dfSTakashi Iwai 
740ff49d1dfSTakashi Iwai 	rmidi->eps[STR_IN] = ep_in;
741ff49d1dfSTakashi Iwai 	rmidi->eps[STR_OUT] = ep_out;
742ff49d1dfSTakashi Iwai 	if (ep_in) {
743ff49d1dfSTakashi Iwai 		ep_in->pair = ep_out;
744ff49d1dfSTakashi Iwai 		ep_in->rmidi = rmidi;
7456b41e64aSTakashi Iwai 		ep_in->ump = ump;
746ff49d1dfSTakashi Iwai 	}
747ff49d1dfSTakashi Iwai 	if (ep_out) {
748ff49d1dfSTakashi Iwai 		ep_out->pair = ep_in;
749ff49d1dfSTakashi Iwai 		ep_out->rmidi = rmidi;
7506b41e64aSTakashi Iwai 		ep_out->ump = ump;
751ff49d1dfSTakashi Iwai 	}
752ff49d1dfSTakashi Iwai 
753ff49d1dfSTakashi Iwai 	list_add_tail(&rmidi->list, &umidi->rawmidi_list);
754ff49d1dfSTakashi Iwai 	return 0;
755ff49d1dfSTakashi Iwai }
756ff49d1dfSTakashi Iwai 
757ff49d1dfSTakashi Iwai /* find the UMP EP with the given USB block id */
758ff49d1dfSTakashi Iwai static struct snd_usb_midi2_ump *
find_midi2_ump(struct snd_usb_midi2_interface * umidi,int blk_id)759ff49d1dfSTakashi Iwai find_midi2_ump(struct snd_usb_midi2_interface *umidi, int blk_id)
760ff49d1dfSTakashi Iwai {
761ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_ump *rmidi;
762ff49d1dfSTakashi Iwai 
763ff49d1dfSTakashi Iwai 	list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {
764ff49d1dfSTakashi Iwai 		if (rmidi->usb_block_id == blk_id)
765ff49d1dfSTakashi Iwai 			return rmidi;
766ff49d1dfSTakashi Iwai 	}
767ff49d1dfSTakashi Iwai 	return NULL;
768ff49d1dfSTakashi Iwai }
769ff49d1dfSTakashi Iwai 
770ff49d1dfSTakashi Iwai /* look for the matching output endpoint and create UMP object if found */
find_matching_ep_partner(struct snd_usb_midi2_interface * umidi,struct snd_usb_midi2_endpoint * ep,int blk_id)771ff49d1dfSTakashi Iwai static int find_matching_ep_partner(struct snd_usb_midi2_interface *umidi,
772ff49d1dfSTakashi Iwai 				    struct snd_usb_midi2_endpoint *ep,
773ff49d1dfSTakashi Iwai 				    int blk_id)
774ff49d1dfSTakashi Iwai {
775ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *pair_ep;
776ff49d1dfSTakashi Iwai 	int blk;
777ff49d1dfSTakashi Iwai 
778ff49d1dfSTakashi Iwai 	usb_audio_dbg(umidi->chip, "Looking for a pair for EP-in 0x%02x\n",
779ff49d1dfSTakashi Iwai 		      ep->endpoint);
780ff49d1dfSTakashi Iwai 	list_for_each_entry(pair_ep, &umidi->ep_list, list) {
781ff49d1dfSTakashi Iwai 		if (pair_ep->direction != STR_OUT)
782ff49d1dfSTakashi Iwai 			continue;
783ff49d1dfSTakashi Iwai 		if (pair_ep->pair)
784ff49d1dfSTakashi Iwai 			continue; /* already paired */
785ff49d1dfSTakashi Iwai 		for (blk = 0; blk < pair_ep->ms_ep->bNumGrpTrmBlock; blk++) {
786ff49d1dfSTakashi Iwai 			if (pair_ep->ms_ep->baAssoGrpTrmBlkID[blk] == blk_id) {
787ff49d1dfSTakashi Iwai 				usb_audio_dbg(umidi->chip,
788ff49d1dfSTakashi Iwai 					      "Found a match with EP-out 0x%02x blk %d\n",
789ff49d1dfSTakashi Iwai 					      pair_ep->endpoint, blk);
790ff49d1dfSTakashi Iwai 				return create_midi2_ump(umidi, ep, pair_ep, blk_id);
791ff49d1dfSTakashi Iwai 			}
792ff49d1dfSTakashi Iwai 		}
793ff49d1dfSTakashi Iwai 	}
794ff49d1dfSTakashi Iwai 	return 0;
795ff49d1dfSTakashi Iwai }
796ff49d1dfSTakashi Iwai 
79754852e8fSTakashi Iwai /* Call UMP helper to parse UMP endpoints;
79854852e8fSTakashi Iwai  * this needs to be called after starting the input streams for bi-directional
79954852e8fSTakashi Iwai  * communications
80054852e8fSTakashi Iwai  */
parse_ump_endpoints(struct snd_usb_midi2_interface * umidi)80154852e8fSTakashi Iwai static int parse_ump_endpoints(struct snd_usb_midi2_interface *umidi)
80254852e8fSTakashi Iwai {
80354852e8fSTakashi Iwai 	struct snd_usb_midi2_ump *rmidi;
80454852e8fSTakashi Iwai 	int err;
80554852e8fSTakashi Iwai 
80654852e8fSTakashi Iwai 	list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {
80754852e8fSTakashi Iwai 		if (!rmidi->ump ||
80854852e8fSTakashi Iwai 		    !(rmidi->ump->core.info_flags & SNDRV_RAWMIDI_INFO_DUPLEX))
80954852e8fSTakashi Iwai 			continue;
81054852e8fSTakashi Iwai 		err = snd_ump_parse_endpoint(rmidi->ump);
81154852e8fSTakashi Iwai 		if (!err) {
81254852e8fSTakashi Iwai 			rmidi->ump_parsed = true;
81354852e8fSTakashi Iwai 		} else {
81454852e8fSTakashi Iwai 			if (err == -ENOMEM)
81554852e8fSTakashi Iwai 				return err;
81654852e8fSTakashi Iwai 			/* fall back to GTB later */
81754852e8fSTakashi Iwai 		}
81854852e8fSTakashi Iwai 	}
81954852e8fSTakashi Iwai 	return 0;
82054852e8fSTakashi Iwai }
82154852e8fSTakashi Iwai 
822d9c99876STakashi Iwai /* create a UMP block from a GTB entry */
create_gtb_block(struct snd_usb_midi2_ump * rmidi,int dir,int blk)823d9c99876STakashi Iwai static int create_gtb_block(struct snd_usb_midi2_ump *rmidi, int dir, int blk)
824d9c99876STakashi Iwai {
825d9c99876STakashi Iwai 	struct snd_usb_midi2_interface *umidi = rmidi->umidi;
826d9c99876STakashi Iwai 	const struct usb_ms20_gr_trm_block_descriptor *desc;
827d9c99876STakashi Iwai 	struct snd_ump_block *fb;
828d9c99876STakashi Iwai 	int type, err;
829d9c99876STakashi Iwai 
830d9c99876STakashi Iwai 	desc = find_group_terminal_block(umidi, blk);
831d9c99876STakashi Iwai 	if (!desc)
832d9c99876STakashi Iwai 		return 0;
833d9c99876STakashi Iwai 
834d9c99876STakashi Iwai 	usb_audio_dbg(umidi->chip,
835d9c99876STakashi Iwai 		      "GTB %d: type=%d, group=%d/%d, protocol=%d, in bw=%d, out bw=%d\n",
836d9c99876STakashi Iwai 		      blk, desc->bGrpTrmBlkType, desc->nGroupTrm,
837d9c99876STakashi Iwai 		      desc->nNumGroupTrm, desc->bMIDIProtocol,
838d9c99876STakashi Iwai 		      __le16_to_cpu(desc->wMaxInputBandwidth),
839d9c99876STakashi Iwai 		      __le16_to_cpu(desc->wMaxOutputBandwidth));
840d9c99876STakashi Iwai 
841d9c99876STakashi Iwai 	/* assign the direction */
842d9c99876STakashi Iwai 	switch (desc->bGrpTrmBlkType) {
843d9c99876STakashi Iwai 	case USB_MS_GR_TRM_BLOCK_TYPE_BIDIRECTIONAL:
844d9c99876STakashi Iwai 		type = SNDRV_UMP_DIR_BIDIRECTION;
845d9c99876STakashi Iwai 		break;
846d9c99876STakashi Iwai 	case USB_MS_GR_TRM_BLOCK_TYPE_INPUT_ONLY:
847d9c99876STakashi Iwai 		type = SNDRV_UMP_DIR_INPUT;
848d9c99876STakashi Iwai 		break;
849d9c99876STakashi Iwai 	case USB_MS_GR_TRM_BLOCK_TYPE_OUTPUT_ONLY:
850d9c99876STakashi Iwai 		type = SNDRV_UMP_DIR_OUTPUT;
851d9c99876STakashi Iwai 		break;
852d9c99876STakashi Iwai 	default:
853d9c99876STakashi Iwai 		usb_audio_dbg(umidi->chip, "Unsupported GTB type %d\n",
854d9c99876STakashi Iwai 			      desc->bGrpTrmBlkType);
855d9c99876STakashi Iwai 		return 0; /* unsupported */
856d9c99876STakashi Iwai 	}
857d9c99876STakashi Iwai 
858d9c99876STakashi Iwai 	/* guess work: set blk-1 as the (0-based) block ID */
859d9c99876STakashi Iwai 	err = snd_ump_block_new(rmidi->ump, blk - 1, type,
860d9c99876STakashi Iwai 				desc->nGroupTrm, desc->nNumGroupTrm,
861d9c99876STakashi Iwai 				&fb);
862d9c99876STakashi Iwai 	if (err == -EBUSY)
863d9c99876STakashi Iwai 		return 0; /* already present */
864d9c99876STakashi Iwai 	else if (err)
865d9c99876STakashi Iwai 		return err;
866d9c99876STakashi Iwai 
867d9c99876STakashi Iwai 	if (desc->iBlockItem)
868d9c99876STakashi Iwai 		usb_string(rmidi->dev, desc->iBlockItem,
869d9c99876STakashi Iwai 			   fb->info.name, sizeof(fb->info.name));
870d9c99876STakashi Iwai 
871d9c99876STakashi Iwai 	if (__le16_to_cpu(desc->wMaxInputBandwidth) == 1 ||
872d9c99876STakashi Iwai 	    __le16_to_cpu(desc->wMaxOutputBandwidth) == 1)
873d9c99876STakashi Iwai 		fb->info.flags |= SNDRV_UMP_BLOCK_IS_MIDI1 |
874d9c99876STakashi Iwai 			SNDRV_UMP_BLOCK_IS_LOWSPEED;
875d9c99876STakashi Iwai 
876*8bb7b689STakashi Iwai 	snd_ump_update_group_attrs(rmidi->ump);
877*8bb7b689STakashi Iwai 
878d9c99876STakashi Iwai 	usb_audio_dbg(umidi->chip,
879d9c99876STakashi Iwai 		      "Created a UMP block %d from GTB, name=%s\n",
880d9c99876STakashi Iwai 		      blk, fb->info.name);
881d9c99876STakashi Iwai 	return 0;
882d9c99876STakashi Iwai }
883d9c99876STakashi Iwai 
884d9c99876STakashi Iwai /* Create UMP blocks for each UMP EP */
create_blocks_from_gtb(struct snd_usb_midi2_interface * umidi)885d9c99876STakashi Iwai static int create_blocks_from_gtb(struct snd_usb_midi2_interface *umidi)
886d9c99876STakashi Iwai {
887d9c99876STakashi Iwai 	struct snd_usb_midi2_ump *rmidi;
888d9c99876STakashi Iwai 	int i, blk, err, dir;
889d9c99876STakashi Iwai 
890d9c99876STakashi Iwai 	list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {
891d9c99876STakashi Iwai 		if (!rmidi->ump)
892d9c99876STakashi Iwai 			continue;
893d9c99876STakashi Iwai 		/* Blocks have been already created? */
89454852e8fSTakashi Iwai 		if (rmidi->ump_parsed || rmidi->ump->info.num_blocks)
895d9c99876STakashi Iwai 			continue;
89601dfa8e9STakashi Iwai 		/* GTB is static-only */
89701dfa8e9STakashi Iwai 		rmidi->ump->info.flags |= SNDRV_UMP_EP_INFO_STATIC_BLOCKS;
898d9c99876STakashi Iwai 		/* loop over GTBs */
899d9c99876STakashi Iwai 		for (dir = 0; dir < 2; dir++) {
900d9c99876STakashi Iwai 			if (!rmidi->eps[dir])
901d9c99876STakashi Iwai 				continue;
902d9c99876STakashi Iwai 			for (i = 0; i < rmidi->eps[dir]->ms_ep->bNumGrpTrmBlock; i++) {
903d9c99876STakashi Iwai 				blk = rmidi->eps[dir]->ms_ep->baAssoGrpTrmBlkID[i];
904d9c99876STakashi Iwai 				err = create_gtb_block(rmidi, dir, blk);
905d9c99876STakashi Iwai 				if (err < 0)
906d9c99876STakashi Iwai 					return err;
907d9c99876STakashi Iwai 			}
908d9c99876STakashi Iwai 		}
909d9c99876STakashi Iwai 	}
910d9c99876STakashi Iwai 
911d9c99876STakashi Iwai 	return 0;
912d9c99876STakashi Iwai }
913d9c99876STakashi Iwai 
914ec362b63STakashi Iwai /* attach legacy rawmidis */
attach_legacy_rawmidi(struct snd_usb_midi2_interface * umidi)915ec362b63STakashi Iwai static int attach_legacy_rawmidi(struct snd_usb_midi2_interface *umidi)
916ec362b63STakashi Iwai {
917ec362b63STakashi Iwai #if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)
918ec362b63STakashi Iwai 	struct snd_usb_midi2_ump *rmidi;
919ec362b63STakashi Iwai 	int err;
920ec362b63STakashi Iwai 
921ec362b63STakashi Iwai 	list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {
922ec362b63STakashi Iwai 		err = snd_ump_attach_legacy_rawmidi(rmidi->ump,
923ec362b63STakashi Iwai 						    "Legacy MIDI",
924ec362b63STakashi Iwai 						    umidi->chip->num_rawmidis);
925ec362b63STakashi Iwai 		if (err < 0)
926ec362b63STakashi Iwai 			return err;
927ec362b63STakashi Iwai 		umidi->chip->num_rawmidis++;
928ec362b63STakashi Iwai 	}
929ec362b63STakashi Iwai #endif
930ec362b63STakashi Iwai 	return 0;
931ec362b63STakashi Iwai }
932ec362b63STakashi Iwai 
snd_usb_midi_v2_free(struct snd_usb_midi2_interface * umidi)933ff49d1dfSTakashi Iwai static void snd_usb_midi_v2_free(struct snd_usb_midi2_interface *umidi)
934ff49d1dfSTakashi Iwai {
935ff49d1dfSTakashi Iwai 	free_all_midi2_endpoints(umidi);
936ff49d1dfSTakashi Iwai 	free_all_midi2_umps(umidi);
937ff49d1dfSTakashi Iwai 	list_del(&umidi->list);
938ff49d1dfSTakashi Iwai 	kfree(umidi->blk_descs);
939ff49d1dfSTakashi Iwai 	kfree(umidi);
940ff49d1dfSTakashi Iwai }
941ff49d1dfSTakashi Iwai 
942ff49d1dfSTakashi Iwai /* parse the interface for MIDI 2.0 */
parse_midi_2_0(struct snd_usb_midi2_interface * umidi)943ff49d1dfSTakashi Iwai static int parse_midi_2_0(struct snd_usb_midi2_interface *umidi)
944ff49d1dfSTakashi Iwai {
945ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep;
946ff49d1dfSTakashi Iwai 	int blk, id, err;
947ff49d1dfSTakashi Iwai 
948ff49d1dfSTakashi Iwai 	/* First, create an object for each USB MIDI Endpoint */
949ff49d1dfSTakashi Iwai 	err = parse_midi_2_0_endpoints(umidi);
950ff49d1dfSTakashi Iwai 	if (err < 0)
951ff49d1dfSTakashi Iwai 		return err;
952ff49d1dfSTakashi Iwai 	if (list_empty(&umidi->ep_list)) {
953ff49d1dfSTakashi Iwai 		usb_audio_warn(umidi->chip, "No MIDI endpoints found\n");
954ff49d1dfSTakashi Iwai 		return -ENODEV;
955ff49d1dfSTakashi Iwai 	}
956ff49d1dfSTakashi Iwai 
957ff49d1dfSTakashi Iwai 	/*
958ff49d1dfSTakashi Iwai 	 * Next, look for EP I/O pairs that are found in group terminal blocks
959ff49d1dfSTakashi Iwai 	 * A UMP object is created for each EP I/O pair as bidirecitonal
960ff49d1dfSTakashi Iwai 	 * UMP EP
961ff49d1dfSTakashi Iwai 	 */
962ff49d1dfSTakashi Iwai 	list_for_each_entry(ep, &umidi->ep_list, list) {
963ff49d1dfSTakashi Iwai 		/* only input in this loop; output is matched in find_midi_ump() */
964ff49d1dfSTakashi Iwai 		if (ep->direction != STR_IN)
965ff49d1dfSTakashi Iwai 			continue;
966ff49d1dfSTakashi Iwai 		for (blk = 0; blk < ep->ms_ep->bNumGrpTrmBlock; blk++) {
967ff49d1dfSTakashi Iwai 			id = ep->ms_ep->baAssoGrpTrmBlkID[blk];
968ff49d1dfSTakashi Iwai 			err = find_matching_ep_partner(umidi, ep, id);
969ff49d1dfSTakashi Iwai 			if (err < 0)
970ff49d1dfSTakashi Iwai 				return err;
971ff49d1dfSTakashi Iwai 		}
972ff49d1dfSTakashi Iwai 	}
973ff49d1dfSTakashi Iwai 
974ff49d1dfSTakashi Iwai 	/*
975ff49d1dfSTakashi Iwai 	 * For the remaining EPs, treat as singles, create a UMP object with
976ff49d1dfSTakashi Iwai 	 * unidirectional EP
977ff49d1dfSTakashi Iwai 	 */
978ff49d1dfSTakashi Iwai 	list_for_each_entry(ep, &umidi->ep_list, list) {
979ff49d1dfSTakashi Iwai 		if (ep->rmidi)
980ff49d1dfSTakashi Iwai 			continue; /* already paired */
981ff49d1dfSTakashi Iwai 		for (blk = 0; blk < ep->ms_ep->bNumGrpTrmBlock; blk++) {
982ff49d1dfSTakashi Iwai 			id = ep->ms_ep->baAssoGrpTrmBlkID[blk];
983ff49d1dfSTakashi Iwai 			if (find_midi2_ump(umidi, id))
984ff49d1dfSTakashi Iwai 				continue;
985ff49d1dfSTakashi Iwai 			usb_audio_dbg(umidi->chip,
986ff49d1dfSTakashi Iwai 				      "Creating a unidirection UMP for EP=0x%02x, blk=%d\n",
987ff49d1dfSTakashi Iwai 				      ep->endpoint, id);
988ff49d1dfSTakashi Iwai 			if (ep->direction == STR_IN)
989ff49d1dfSTakashi Iwai 				err = create_midi2_ump(umidi, ep, NULL, id);
990ff49d1dfSTakashi Iwai 			else
991ff49d1dfSTakashi Iwai 				err = create_midi2_ump(umidi, NULL, ep, id);
992ff49d1dfSTakashi Iwai 			if (err < 0)
993ff49d1dfSTakashi Iwai 				return err;
994ff49d1dfSTakashi Iwai 			break;
995ff49d1dfSTakashi Iwai 		}
996ff49d1dfSTakashi Iwai 	}
997ff49d1dfSTakashi Iwai 
9985f11dd93STakashi Iwai 	return 0;
999ff49d1dfSTakashi Iwai }
1000ff49d1dfSTakashi Iwai 
1001ff49d1dfSTakashi Iwai /* is the given interface for MIDI 2.0? */
is_midi2_altset(struct usb_host_interface * hostif)1002ff49d1dfSTakashi Iwai static bool is_midi2_altset(struct usb_host_interface *hostif)
1003ff49d1dfSTakashi Iwai {
1004ff49d1dfSTakashi Iwai 	struct usb_ms_header_descriptor *ms_header =
1005ff49d1dfSTakashi Iwai 		(struct usb_ms_header_descriptor *)hostif->extra;
1006ff49d1dfSTakashi Iwai 
1007ff49d1dfSTakashi Iwai 	if (hostif->extralen < 7 ||
1008ff49d1dfSTakashi Iwai 	    ms_header->bLength < 7 ||
1009ff49d1dfSTakashi Iwai 	    ms_header->bDescriptorType != USB_DT_CS_INTERFACE ||
1010ff49d1dfSTakashi Iwai 	    ms_header->bDescriptorSubtype != UAC_HEADER)
1011ff49d1dfSTakashi Iwai 		return false;
1012ff49d1dfSTakashi Iwai 
1013ff49d1dfSTakashi Iwai 	return le16_to_cpu(ms_header->bcdMSC) == USB_MS_REV_MIDI_2_0;
1014ff49d1dfSTakashi Iwai }
1015ff49d1dfSTakashi Iwai 
1016ff49d1dfSTakashi Iwai /* change the altsetting */
set_altset(struct snd_usb_midi2_interface * umidi)1017ff49d1dfSTakashi Iwai static int set_altset(struct snd_usb_midi2_interface *umidi)
1018ff49d1dfSTakashi Iwai {
1019ff49d1dfSTakashi Iwai 	usb_audio_dbg(umidi->chip, "Setting host iface %d:%d\n",
1020ff49d1dfSTakashi Iwai 		      umidi->hostif->desc.bInterfaceNumber,
1021ff49d1dfSTakashi Iwai 		      umidi->hostif->desc.bAlternateSetting);
1022ff49d1dfSTakashi Iwai 	return usb_set_interface(umidi->chip->dev,
1023ff49d1dfSTakashi Iwai 				 umidi->hostif->desc.bInterfaceNumber,
1024ff49d1dfSTakashi Iwai 				 umidi->hostif->desc.bAlternateSetting);
1025ff49d1dfSTakashi Iwai }
1026ff49d1dfSTakashi Iwai 
102706cf3bf0STakashi Iwai /* fill UMP Endpoint name string from USB descriptor */
fill_ump_ep_name(struct snd_ump_endpoint * ump,struct usb_device * dev,int id)102806cf3bf0STakashi Iwai static void fill_ump_ep_name(struct snd_ump_endpoint *ump,
102906cf3bf0STakashi Iwai 			     struct usb_device *dev, int id)
103006cf3bf0STakashi Iwai {
103151701400STakashi Iwai 	int len;
103251701400STakashi Iwai 
103306cf3bf0STakashi Iwai 	usb_string(dev, id, ump->info.name, sizeof(ump->info.name));
103451701400STakashi Iwai 
103551701400STakashi Iwai 	/* trim superfluous "MIDI" suffix */
103651701400STakashi Iwai 	len = strlen(ump->info.name);
103751701400STakashi Iwai 	if (len > 5 && !strcmp(ump->info.name + len - 5, " MIDI"))
103851701400STakashi Iwai 		ump->info.name[len - 5] = 0;
103906cf3bf0STakashi Iwai }
104006cf3bf0STakashi Iwai 
1041ff49d1dfSTakashi Iwai /* fill the fallback name string for each rawmidi instance */
set_fallback_rawmidi_names(struct snd_usb_midi2_interface * umidi)1042ff49d1dfSTakashi Iwai static void set_fallback_rawmidi_names(struct snd_usb_midi2_interface *umidi)
1043ff49d1dfSTakashi Iwai {
104406cf3bf0STakashi Iwai 	struct usb_device *dev = umidi->chip->dev;
1045ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_ump *rmidi;
104606cf3bf0STakashi Iwai 	struct snd_ump_endpoint *ump;
1047ff49d1dfSTakashi Iwai 
1048ff49d1dfSTakashi Iwai 	list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {
104906cf3bf0STakashi Iwai 		ump = rmidi->ump;
105006cf3bf0STakashi Iwai 		/* fill UMP EP name from USB descriptors */
105106cf3bf0STakashi Iwai 		if (!*ump->info.name && umidi->hostif->desc.iInterface)
105206cf3bf0STakashi Iwai 			fill_ump_ep_name(ump, dev, umidi->hostif->desc.iInterface);
105306cf3bf0STakashi Iwai 		else if (!*ump->info.name && dev->descriptor.iProduct)
105406cf3bf0STakashi Iwai 			fill_ump_ep_name(ump, dev, dev->descriptor.iProduct);
105506cf3bf0STakashi Iwai 		/* fill fallback name */
105606cf3bf0STakashi Iwai 		if (!*ump->info.name)
105706cf3bf0STakashi Iwai 			sprintf(ump->info.name, "USB MIDI %d", rmidi->index);
105806cf3bf0STakashi Iwai 		/* copy as rawmidi name if not set */
105906cf3bf0STakashi Iwai 		if (!*ump->core.name)
106006cf3bf0STakashi Iwai 			strscpy(ump->core.name, ump->info.name,
106106cf3bf0STakashi Iwai 				sizeof(ump->core.name));
106206cf3bf0STakashi Iwai 		/* use serial number string as unique UMP product id */
106306cf3bf0STakashi Iwai 		if (!*ump->info.product_id && dev->descriptor.iSerialNumber)
106406cf3bf0STakashi Iwai 			usb_string(dev, dev->descriptor.iSerialNumber,
106506cf3bf0STakashi Iwai 				   ump->info.product_id,
106606cf3bf0STakashi Iwai 				   sizeof(ump->info.product_id));
1067ff49d1dfSTakashi Iwai 	}
1068ff49d1dfSTakashi Iwai }
1069ff49d1dfSTakashi Iwai 
1070ff49d1dfSTakashi Iwai /* create MIDI interface; fallback to MIDI 1.0 if needed */
snd_usb_midi_v2_create(struct snd_usb_audio * chip,struct usb_interface * iface,const struct snd_usb_audio_quirk * quirk,unsigned int usb_id)1071ff49d1dfSTakashi Iwai int snd_usb_midi_v2_create(struct snd_usb_audio *chip,
1072ff49d1dfSTakashi Iwai 			   struct usb_interface *iface,
1073ff49d1dfSTakashi Iwai 			   const struct snd_usb_audio_quirk *quirk,
1074ff49d1dfSTakashi Iwai 			   unsigned int usb_id)
1075ff49d1dfSTakashi Iwai {
1076ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_interface *umidi;
1077ff49d1dfSTakashi Iwai 	struct usb_host_interface *hostif;
1078ff49d1dfSTakashi Iwai 	int err;
1079ff49d1dfSTakashi Iwai 
1080ff49d1dfSTakashi Iwai 	usb_audio_dbg(chip, "Parsing interface %d...\n",
1081ff49d1dfSTakashi Iwai 		      iface->altsetting[0].desc.bInterfaceNumber);
1082ff49d1dfSTakashi Iwai 
1083ff49d1dfSTakashi Iwai 	/* fallback to MIDI 1.0? */
1084ff49d1dfSTakashi Iwai 	if (!midi2_enable) {
1085ff49d1dfSTakashi Iwai 		usb_audio_info(chip, "Falling back to MIDI 1.0 by module option\n");
1086ff49d1dfSTakashi Iwai 		goto fallback_to_midi1;
1087ff49d1dfSTakashi Iwai 	}
1088ff49d1dfSTakashi Iwai 	if ((quirk && quirk->type != QUIRK_MIDI_STANDARD_INTERFACE) ||
1089ff49d1dfSTakashi Iwai 	    iface->num_altsetting < 2) {
1090ff49d1dfSTakashi Iwai 		usb_audio_info(chip, "Quirk or no altest; falling back to MIDI 1.0\n");
1091ff49d1dfSTakashi Iwai 		goto fallback_to_midi1;
1092ff49d1dfSTakashi Iwai 	}
1093ff49d1dfSTakashi Iwai 	hostif = &iface->altsetting[1];
1094ff49d1dfSTakashi Iwai 	if (!is_midi2_altset(hostif)) {
1095ff49d1dfSTakashi Iwai 		usb_audio_info(chip, "No MIDI 2.0 at altset 1, falling back to MIDI 1.0\n");
1096ff49d1dfSTakashi Iwai 		goto fallback_to_midi1;
1097ff49d1dfSTakashi Iwai 	}
1098ff49d1dfSTakashi Iwai 	if (!hostif->desc.bNumEndpoints) {
1099ff49d1dfSTakashi Iwai 		usb_audio_info(chip, "No endpoint at altset 1, falling back to MIDI 1.0\n");
1100ff49d1dfSTakashi Iwai 		goto fallback_to_midi1;
1101ff49d1dfSTakashi Iwai 	}
1102ff49d1dfSTakashi Iwai 
1103ff49d1dfSTakashi Iwai 	usb_audio_dbg(chip, "Creating a MIDI 2.0 instance for %d:%d\n",
1104ff49d1dfSTakashi Iwai 		      hostif->desc.bInterfaceNumber,
1105ff49d1dfSTakashi Iwai 		      hostif->desc.bAlternateSetting);
1106ff49d1dfSTakashi Iwai 
1107ff49d1dfSTakashi Iwai 	umidi = kzalloc(sizeof(*umidi), GFP_KERNEL);
1108ff49d1dfSTakashi Iwai 	if (!umidi)
1109ff49d1dfSTakashi Iwai 		return -ENOMEM;
1110ff49d1dfSTakashi Iwai 	umidi->chip = chip;
1111ff49d1dfSTakashi Iwai 	umidi->iface = iface;
1112ff49d1dfSTakashi Iwai 	umidi->hostif = hostif;
1113ff49d1dfSTakashi Iwai 	INIT_LIST_HEAD(&umidi->rawmidi_list);
1114ff49d1dfSTakashi Iwai 	INIT_LIST_HEAD(&umidi->ep_list);
1115ff49d1dfSTakashi Iwai 
1116ff49d1dfSTakashi Iwai 	list_add_tail(&umidi->list, &chip->midi_v2_list);
1117ff49d1dfSTakashi Iwai 
1118ff49d1dfSTakashi Iwai 	err = set_altset(umidi);
1119ff49d1dfSTakashi Iwai 	if (err < 0) {
1120ff49d1dfSTakashi Iwai 		usb_audio_err(chip, "Failed to set altset\n");
1121ff49d1dfSTakashi Iwai 		goto error;
1122ff49d1dfSTakashi Iwai 	}
1123ff49d1dfSTakashi Iwai 
1124ff49d1dfSTakashi Iwai 	/* assume only altset 1 corresponding to MIDI 2.0 interface */
1125ff49d1dfSTakashi Iwai 	err = parse_midi_2_0(umidi);
1126ff49d1dfSTakashi Iwai 	if (err < 0) {
1127ff49d1dfSTakashi Iwai 		usb_audio_err(chip, "Failed to parse MIDI 2.0 interface\n");
1128ff49d1dfSTakashi Iwai 		goto error;
1129ff49d1dfSTakashi Iwai 	}
1130ff49d1dfSTakashi Iwai 
1131ff49d1dfSTakashi Iwai 	/* parse USB group terminal blocks */
1132ff49d1dfSTakashi Iwai 	err = parse_group_terminal_blocks(umidi);
1133ff49d1dfSTakashi Iwai 	if (err < 0) {
1134ff49d1dfSTakashi Iwai 		usb_audio_err(chip, "Failed to parse GTB\n");
1135ff49d1dfSTakashi Iwai 		goto error;
1136ff49d1dfSTakashi Iwai 	}
1137ff49d1dfSTakashi Iwai 
1138ff49d1dfSTakashi Iwai 	err = start_input_streams(umidi);
1139ff49d1dfSTakashi Iwai 	if (err < 0) {
1140ff49d1dfSTakashi Iwai 		usb_audio_err(chip, "Failed to start input streams\n");
1141ff49d1dfSTakashi Iwai 		goto error;
1142ff49d1dfSTakashi Iwai 	}
1143ff49d1dfSTakashi Iwai 
1144960a1149STakashi Iwai 	if (midi2_ump_probe) {
114554852e8fSTakashi Iwai 		err = parse_ump_endpoints(umidi);
114654852e8fSTakashi Iwai 		if (err < 0) {
114754852e8fSTakashi Iwai 			usb_audio_err(chip, "Failed to parse UMP endpoint\n");
114854852e8fSTakashi Iwai 			goto error;
114954852e8fSTakashi Iwai 		}
1150960a1149STakashi Iwai 	}
115154852e8fSTakashi Iwai 
1152d9c99876STakashi Iwai 	err = create_blocks_from_gtb(umidi);
1153d9c99876STakashi Iwai 	if (err < 0) {
1154d9c99876STakashi Iwai 		usb_audio_err(chip, "Failed to create GTB blocks\n");
1155d9c99876STakashi Iwai 		goto error;
1156d9c99876STakashi Iwai 	}
1157d9c99876STakashi Iwai 
1158ff49d1dfSTakashi Iwai 	set_fallback_rawmidi_names(umidi);
11595f11dd93STakashi Iwai 
11605f11dd93STakashi Iwai 	err = attach_legacy_rawmidi(umidi);
11615f11dd93STakashi Iwai 	if (err < 0) {
11625f11dd93STakashi Iwai 		usb_audio_err(chip, "Failed to create legacy rawmidi\n");
11635f11dd93STakashi Iwai 		goto error;
11645f11dd93STakashi Iwai 	}
11655f11dd93STakashi Iwai 
1166ff49d1dfSTakashi Iwai 	return 0;
1167ff49d1dfSTakashi Iwai 
1168ff49d1dfSTakashi Iwai  error:
1169ff49d1dfSTakashi Iwai 	snd_usb_midi_v2_free(umidi);
1170ff49d1dfSTakashi Iwai 	return err;
1171ff49d1dfSTakashi Iwai 
1172ff49d1dfSTakashi Iwai  fallback_to_midi1:
1173ff49d1dfSTakashi Iwai 	return __snd_usbmidi_create(chip->card, iface, &chip->midi_list,
1174ff49d1dfSTakashi Iwai 				    quirk, usb_id, &chip->num_rawmidis);
1175ff49d1dfSTakashi Iwai }
1176ff49d1dfSTakashi Iwai 
suspend_midi2_endpoint(struct snd_usb_midi2_endpoint * ep)1177ff49d1dfSTakashi Iwai static void suspend_midi2_endpoint(struct snd_usb_midi2_endpoint *ep)
1178ff49d1dfSTakashi Iwai {
1179ff49d1dfSTakashi Iwai 	kill_midi_urbs(ep, true);
1180ff49d1dfSTakashi Iwai 	drain_urb_queue(ep);
1181ff49d1dfSTakashi Iwai }
1182ff49d1dfSTakashi Iwai 
snd_usb_midi_v2_suspend_all(struct snd_usb_audio * chip)1183ff49d1dfSTakashi Iwai void snd_usb_midi_v2_suspend_all(struct snd_usb_audio *chip)
1184ff49d1dfSTakashi Iwai {
1185ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_interface *umidi;
1186ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep;
1187ff49d1dfSTakashi Iwai 
1188ff49d1dfSTakashi Iwai 	list_for_each_entry(umidi, &chip->midi_v2_list, list) {
1189ff49d1dfSTakashi Iwai 		list_for_each_entry(ep, &umidi->ep_list, list)
1190ff49d1dfSTakashi Iwai 			suspend_midi2_endpoint(ep);
1191ff49d1dfSTakashi Iwai 	}
1192ff49d1dfSTakashi Iwai }
1193ff49d1dfSTakashi Iwai 
resume_midi2_endpoint(struct snd_usb_midi2_endpoint * ep)1194ff49d1dfSTakashi Iwai static void resume_midi2_endpoint(struct snd_usb_midi2_endpoint *ep)
1195ff49d1dfSTakashi Iwai {
1196ff49d1dfSTakashi Iwai 	ep->running = ep->suspended;
1197ff49d1dfSTakashi Iwai 	if (ep->direction == STR_IN)
1198ff49d1dfSTakashi Iwai 		submit_io_urbs(ep);
1199ff49d1dfSTakashi Iwai 	/* FIXME: does it all? */
1200ff49d1dfSTakashi Iwai }
1201ff49d1dfSTakashi Iwai 
snd_usb_midi_v2_resume_all(struct snd_usb_audio * chip)1202ff49d1dfSTakashi Iwai void snd_usb_midi_v2_resume_all(struct snd_usb_audio *chip)
1203ff49d1dfSTakashi Iwai {
1204ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_interface *umidi;
1205ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep;
1206ff49d1dfSTakashi Iwai 
1207ff49d1dfSTakashi Iwai 	list_for_each_entry(umidi, &chip->midi_v2_list, list) {
1208ff49d1dfSTakashi Iwai 		set_altset(umidi);
1209ff49d1dfSTakashi Iwai 		list_for_each_entry(ep, &umidi->ep_list, list)
1210ff49d1dfSTakashi Iwai 			resume_midi2_endpoint(ep);
1211ff49d1dfSTakashi Iwai 	}
1212ff49d1dfSTakashi Iwai }
1213ff49d1dfSTakashi Iwai 
snd_usb_midi_v2_disconnect_all(struct snd_usb_audio * chip)1214ff49d1dfSTakashi Iwai void snd_usb_midi_v2_disconnect_all(struct snd_usb_audio *chip)
1215ff49d1dfSTakashi Iwai {
1216ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_interface *umidi;
1217ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_endpoint *ep;
1218ff49d1dfSTakashi Iwai 
1219ff49d1dfSTakashi Iwai 	list_for_each_entry(umidi, &chip->midi_v2_list, list) {
1220ff49d1dfSTakashi Iwai 		umidi->disconnected = 1;
1221ff49d1dfSTakashi Iwai 		list_for_each_entry(ep, &umidi->ep_list, list) {
1222ff49d1dfSTakashi Iwai 			ep->disconnected = 1;
1223ff49d1dfSTakashi Iwai 			kill_midi_urbs(ep, false);
1224ff49d1dfSTakashi Iwai 			drain_urb_queue(ep);
1225ff49d1dfSTakashi Iwai 		}
1226ff49d1dfSTakashi Iwai 	}
1227ff49d1dfSTakashi Iwai }
1228ff49d1dfSTakashi Iwai 
1229ff49d1dfSTakashi Iwai /* release the MIDI instance */
snd_usb_midi_v2_free_all(struct snd_usb_audio * chip)1230ff49d1dfSTakashi Iwai void snd_usb_midi_v2_free_all(struct snd_usb_audio *chip)
1231ff49d1dfSTakashi Iwai {
1232ff49d1dfSTakashi Iwai 	struct snd_usb_midi2_interface *umidi, *next;
1233ff49d1dfSTakashi Iwai 
1234ff49d1dfSTakashi Iwai 	list_for_each_entry_safe(umidi, next, &chip->midi_v2_list, list)
1235ff49d1dfSTakashi Iwai 		snd_usb_midi_v2_free(umidi);
1236ff49d1dfSTakashi Iwai }
1237