~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/usb/midi2.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php