Lines Matching +full:serial +full:- +full:midi

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * MIDI 2.0 support
15 #include <linux/usb/midi.h>
16 #include <linux/usb/midi-v2.h>
22 #include "midi.h"
28 MODULE_PARM_DESC(midi2_enable, "Enable MIDI 2.0 support.");
54 /* A USB MIDI input/output endpoint */
74 bool disconnected; /* shadow of umidi->disconnected */
75 struct list_head list; /* list to umidi->ep_list */
79 /* A UMP endpoint - one or two USB MIDI endpoints are assigned */
82 struct snd_usb_midi2_interface *umidi; /* reference to MIDI iface */
84 struct snd_usb_midi2_endpoint *eps[2]; /* USB MIDI endpoints */
88 struct list_head list; /* list to umidi->rawmidi_list */
91 /* top-level instance per USB MIDI interface */
93 struct snd_usb_audio *chip; /* assigned USB-audio card */
101 struct list_head list; /* list to chip->midi_v2_list */
112 if (ep->disconnected) in do_submit_urbs_locked()
115 while (ep->urb_free) { in do_submit_urbs_locked()
116 index = find_first_bit(&ep->urb_free, ep->num_urbs); in do_submit_urbs_locked()
117 if (index >= ep->num_urbs) in do_submit_urbs_locked()
119 ctx = &ep->urbs[index]; in do_submit_urbs_locked()
120 err = prepare(ep, ctx->urb); in do_submit_urbs_locked()
123 if (!ctx->urb->transfer_buffer_length) in do_submit_urbs_locked()
125 ctx->urb->dev = ep->dev; in do_submit_urbs_locked()
126 err = usb_submit_urb(ctx->urb, GFP_ATOMIC); in do_submit_urbs_locked()
128 dev_dbg(&ep->dev->dev, in do_submit_urbs_locked()
132 clear_bit(index, &ep->urb_free); in do_submit_urbs_locked()
142 count = snd_ump_transmit(ep->ump, urb->transfer_buffer, in prepare_output_urb()
143 ep->packets); in prepare_output_urb()
145 dev_dbg(&ep->dev->dev, "rawmidi transmit error %d\n", count); in prepare_output_urb()
148 cpu_to_le32_array((u32 *)urb->transfer_buffer, count >> 2); in prepare_output_urb()
149 urb->transfer_buffer_length = count; in prepare_output_urb()
158 /* URB completion for output; re-filling and re-submit */
161 struct snd_usb_midi2_urb *ctx = urb->context; in output_urb_complete()
162 struct snd_usb_midi2_endpoint *ep = ctx->ep; in output_urb_complete()
165 spin_lock_irqsave(&ep->lock, flags); in output_urb_complete()
166 set_bit(ctx->index, &ep->urb_free); in output_urb_complete()
167 if (urb->status >= 0 && atomic_read(&ep->running)) in output_urb_complete()
169 if (ep->urb_free == ep->urb_free_mask) in output_urb_complete()
170 wake_up(&ep->wait); in output_urb_complete()
171 spin_unlock_irqrestore(&ep->lock, flags); in output_urb_complete()
178 urb->transfer_buffer_length = ep->packets; in prepare_input_urb()
190 struct snd_usb_midi2_urb *ctx = urb->context; in input_urb_complete()
191 struct snd_usb_midi2_endpoint *ep = ctx->ep; in input_urb_complete()
195 spin_lock_irqsave(&ep->lock, flags); in input_urb_complete()
196 if (ep->disconnected || urb->status < 0) in input_urb_complete()
198 len = urb->actual_length; in input_urb_complete()
200 if (len > ep->packets) in input_urb_complete()
201 len = ep->packets; in input_urb_complete()
203 le32_to_cpu_array((u32 *)urb->transfer_buffer, len >> 2); in input_urb_complete()
204 snd_ump_receive(ep->ump, (u32 *)urb->transfer_buffer, len); in input_urb_complete()
207 set_bit(ctx->index, &ep->urb_free); in input_urb_complete()
209 if (ep->urb_free == ep->urb_free_mask) in input_urb_complete()
210 wake_up(&ep->wait); in input_urb_complete()
211 spin_unlock_irqrestore(&ep->lock, flags); in input_urb_complete()
221 spin_lock_irqsave(&ep->lock, flags); in submit_io_urbs()
222 if (ep->direction == STR_IN) in submit_io_urbs()
226 spin_unlock_irqrestore(&ep->lock, flags); in submit_io_urbs()
237 ep->suspended = ep->running; in kill_midi_urbs()
238 atomic_set(&ep->running, 0); in kill_midi_urbs()
239 for (i = 0; i < ep->num_urbs; i++) { in kill_midi_urbs()
240 if (!ep->urbs[i].urb) in kill_midi_urbs()
242 usb_kill_urb(ep->urbs[i].urb); in kill_midi_urbs()
251 spin_lock_irq(&ep->lock); in drain_urb_queue()
252 atomic_set(&ep->running, 0); in drain_urb_queue()
253 wait_event_lock_irq_timeout(ep->wait, in drain_urb_queue()
254 ep->disconnected || in drain_urb_queue()
255 ep->urb_free == ep->urb_free_mask, in drain_urb_queue()
256 ep->lock, msecs_to_jiffies(500)); in drain_urb_queue()
257 spin_unlock_irq(&ep->lock); in drain_urb_queue()
269 ctx = &ep->urbs[i]; in free_midi_urbs()
270 if (!ctx->urb) in free_midi_urbs()
272 usb_free_coherent(ep->dev, ep->packets, in free_midi_urbs()
273 ctx->urb->transfer_buffer, in free_midi_urbs()
274 ctx->urb->transfer_dma); in free_midi_urbs()
275 usb_free_urb(ctx->urb); in free_midi_urbs()
276 ctx->urb = NULL; in free_midi_urbs()
278 ep->num_urbs = 0; in free_midi_urbs()
291 endpoint = ep->endpoint; in alloc_midi_urbs()
292 len = ep->packets; in alloc_midi_urbs()
293 if (ep->direction == STR_IN) in alloc_midi_urbs()
298 ep->num_urbs = 0; in alloc_midi_urbs()
299 ep->urb_free = ep->urb_free_mask = 0; in alloc_midi_urbs()
301 ctx = &ep->urbs[i]; in alloc_midi_urbs()
302 ctx->index = i; in alloc_midi_urbs()
303 ctx->urb = usb_alloc_urb(0, GFP_KERNEL); in alloc_midi_urbs()
304 if (!ctx->urb) { in alloc_midi_urbs()
305 dev_err(&ep->dev->dev, "URB alloc failed\n"); in alloc_midi_urbs()
306 return -ENOMEM; in alloc_midi_urbs()
308 ctx->ep = ep; in alloc_midi_urbs()
309 buffer = usb_alloc_coherent(ep->dev, len, GFP_KERNEL, in alloc_midi_urbs()
310 &ctx->urb->transfer_dma); in alloc_midi_urbs()
312 dev_err(&ep->dev->dev, in alloc_midi_urbs()
314 return -ENOMEM; in alloc_midi_urbs()
316 if (ep->interval) in alloc_midi_urbs()
317 usb_fill_int_urb(ctx->urb, ep->dev, ep->pipe, in alloc_midi_urbs()
318 buffer, len, comp, ctx, ep->interval); in alloc_midi_urbs()
320 usb_fill_bulk_urb(ctx->urb, ep->dev, ep->pipe, in alloc_midi_urbs()
322 err = usb_urb_ep_type_check(ctx->urb); in alloc_midi_urbs()
324 dev_err(&ep->dev->dev, "invalid MIDI EP %x\n", in alloc_midi_urbs()
328 ctx->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; in alloc_midi_urbs()
329 ep->num_urbs++; in alloc_midi_urbs()
331 ep->urb_free = ep->urb_free_mask = GENMASK(ep->num_urbs - 1, 0); in alloc_midi_urbs()
338 struct snd_usb_midi2_ump *rmidi = ump->private_data; in ump_to_endpoint()
340 return rmidi->eps[dir]; in ump_to_endpoint()
349 if (!ep || !ep->endpoint) in snd_usb_midi_v2_open()
350 return -ENODEV; in snd_usb_midi_v2_open()
351 if (ep->disconnected) in snd_usb_midi_v2_open()
352 return -EIO; in snd_usb_midi_v2_open()
353 if (ep->direction == STR_OUT) { in snd_usb_midi_v2_open()
368 if (ep->direction == STR_OUT) { in snd_usb_midi_v2_close()
381 atomic_set(&ep->running, up); in snd_usb_midi_v2_trigger()
382 if (up && ep->direction == STR_OUT && !ep->disconnected) in snd_usb_midi_v2_trigger()
400 list_for_each_entry(ep, &umidi->ep_list, list) { in start_input_streams()
401 if (ep->direction == STR_IN) { in start_input_streams()
408 list_for_each_entry(ep, &umidi->ep_list, list) { in start_input_streams()
409 if (ep->direction == STR_IN) in start_input_streams()
416 list_for_each_entry(ep, &umidi->ep_list, list) { in start_input_streams()
417 if (ep->direction == STR_IN) in start_input_streams()
431 /* create a USB MIDI 2.0 endpoint object */
439 usb_audio_dbg(umidi->chip, "Creating an EP 0x%02x, #GTB=%d\n", in create_midi2_endpoint()
440 hostep->desc.bEndpointAddress, in create_midi2_endpoint()
441 ms_ep->bNumGrpTrmBlock); in create_midi2_endpoint()
445 return -ENOMEM; in create_midi2_endpoint()
447 spin_lock_init(&ep->lock); in create_midi2_endpoint()
448 init_waitqueue_head(&ep->wait); in create_midi2_endpoint()
449 ep->dev = umidi->chip->dev; in create_midi2_endpoint()
450 endpoint = hostep->desc.bEndpointAddress; in create_midi2_endpoint()
453 ep->endpoint = endpoint; in create_midi2_endpoint()
454 ep->direction = dir; in create_midi2_endpoint()
455 ep->ms_ep = ms_ep; in create_midi2_endpoint()
456 if (usb_endpoint_xfer_int(&hostep->desc)) in create_midi2_endpoint()
457 ep->interval = hostep->desc.bInterval; in create_midi2_endpoint()
459 ep->interval = 0; in create_midi2_endpoint()
461 if (ep->interval) in create_midi2_endpoint()
462 ep->pipe = usb_rcvintpipe(ep->dev, endpoint); in create_midi2_endpoint()
464 ep->pipe = usb_rcvbulkpipe(ep->dev, endpoint); in create_midi2_endpoint()
466 if (ep->interval) in create_midi2_endpoint()
467 ep->pipe = usb_sndintpipe(ep->dev, endpoint); in create_midi2_endpoint()
469 ep->pipe = usb_sndbulkpipe(ep->dev, endpoint); in create_midi2_endpoint()
471 ep->packets = usb_maxpacket(ep->dev, ep->pipe); in create_midi2_endpoint()
472 list_add_tail(&ep->list, &umidi->ep_list); in create_midi2_endpoint()
480 list_del(&ep->list); in free_midi2_endpoint()
490 while (!list_empty(&umidi->ep_list)) { in free_all_midi2_endpoints()
491 ep = list_first_entry(&umidi->ep_list, in free_all_midi2_endpoints()
497 /* find a MIDI STREAMING descriptor with a given subtype */
501 unsigned char *extra = hostep->extra; in find_usb_ms_endpoint_descriptor()
502 int extralen = hostep->extralen; in find_usb_ms_endpoint_descriptor()
508 if (ms_ep->bLength > 3 && in find_usb_ms_endpoint_descriptor()
509 ms_ep->bDescriptorType == USB_DT_CS_ENDPOINT && in find_usb_ms_endpoint_descriptor()
510 ms_ep->bDescriptorSubtype == subtype) in find_usb_ms_endpoint_descriptor()
514 extralen -= extra[0]; in find_usb_ms_endpoint_descriptor()
523 struct usb_host_interface *hostif = umidi->hostif; in get_group_terminal_block_descs()
524 struct usb_device *dev = umidi->chip->dev; in get_group_terminal_block_descs()
532 USB_DT_CS_GR_TRM_BLOCK << 8 | hostif->desc.bAlternateSetting, in get_group_terminal_block_descs()
533 hostif->desc.bInterfaceNumber, in get_group_terminal_block_descs()
539 dev_err(&dev->dev, "Failed to get GTB descriptors for %d:%d\n", in get_group_terminal_block_descs()
540 hostif->desc.bInterfaceNumber, hostif->desc.bAlternateSetting); in get_group_terminal_block_descs()
541 return -EINVAL; in get_group_terminal_block_descs()
546 return -ENOMEM; in get_group_terminal_block_descs()
551 USB_DT_CS_GR_TRM_BLOCK << 8 | hostif->desc.bAlternateSetting, in get_group_terminal_block_descs()
552 hostif->desc.bInterfaceNumber, data, size); in get_group_terminal_block_descs()
558 umidi->blk_descs = data; in get_group_terminal_block_descs()
559 umidi->blk_desc_size = size; in get_group_terminal_block_descs()
567 const unsigned char *data = umidi->blk_descs; in find_group_terminal_block()
568 int size = umidi->blk_desc_size; in find_group_terminal_block()
571 size -= sizeof(struct usb_ms20_gr_trm_block_header_descriptor); in find_group_terminal_block()
575 if (desc->bLength >= sizeof(*desc) && in find_group_terminal_block()
576 desc->bDescriptorType == USB_DT_CS_GR_TRM_BLOCK && in find_group_terminal_block()
577 desc->bDescriptorSubtype == USB_MS_GR_TRM_BLOCK && in find_group_terminal_block()
578 desc->bGrpTrmBlkID == id) in find_group_terminal_block()
580 size -= *data; in find_group_terminal_block()
591 struct snd_ump_endpoint *ump = rmidi->ump; in parse_group_terminal_block()
595 switch (desc->bMIDIProtocol) { in parse_group_terminal_block()
610 if (!ump->info.protocol) in parse_group_terminal_block()
611 ump->info.protocol = protocol; in parse_group_terminal_block()
614 switch (desc->bMIDIProtocol) { in parse_group_terminal_block()
623 ump->info.protocol_caps |= protocol_caps; in parse_group_terminal_block()
637 if (!umidi->blk_descs) in parse_group_terminal_blocks()
640 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) { in parse_group_terminal_blocks()
641 desc = find_group_terminal_block(umidi, rmidi->usb_block_id); in parse_group_terminal_blocks()
655 struct usb_host_interface *hostif = umidi->hostif; in parse_midi_2_0_endpoints()
660 for (i = 0; i < hostif->desc.bNumEndpoints; i++) { in parse_midi_2_0_endpoints()
661 hostep = &hostif->endpoint[i]; in parse_midi_2_0_endpoints()
662 if (!usb_endpoint_xfer_bulk(&hostep->desc) && in parse_midi_2_0_endpoints()
663 !usb_endpoint_xfer_int(&hostep->desc)) in parse_midi_2_0_endpoints()
668 if (ms_ep->bLength <= sizeof(*ms_ep)) in parse_midi_2_0_endpoints()
670 if (!ms_ep->bNumGrpTrmBlock) in parse_midi_2_0_endpoints()
672 if (ms_ep->bLength < sizeof(*ms_ep) + ms_ep->bNumGrpTrmBlock) in parse_midi_2_0_endpoints()
685 while (!list_empty(&umidi->rawmidi_list)) { in free_all_midi2_umps()
686 rmidi = list_first_entry(&umidi->rawmidi_list, in free_all_midi2_umps()
688 list_del(&rmidi->list); in free_all_midi2_umps()
706 return -ENOMEM; in create_midi2_ump()
707 INIT_LIST_HEAD(&rmidi->list); in create_midi2_ump()
708 rmidi->dev = umidi->chip->dev; in create_midi2_ump()
709 rmidi->umidi = umidi; in create_midi2_ump()
710 rmidi->usb_block_id = blk_id; in create_midi2_ump()
712 rmidi->index = umidi->chip->num_rawmidis; in create_midi2_ump()
713 snprintf(idstr, sizeof(idstr), "UMP %d", rmidi->index); in create_midi2_ump()
716 err = snd_ump_endpoint_new(umidi->chip->card, idstr, rmidi->index, in create_midi2_ump()
719 usb_audio_dbg(umidi->chip, "Failed to create a UMP object\n"); in create_midi2_ump()
724 rmidi->ump = ump; in create_midi2_ump()
725 umidi->chip->num_rawmidis++; in create_midi2_ump()
727 ump->private_data = rmidi; in create_midi2_ump()
728 ump->ops = &snd_usb_midi_v2_ump_ops; in create_midi2_ump()
730 rmidi->eps[STR_IN] = ep_in; in create_midi2_ump()
731 rmidi->eps[STR_OUT] = ep_out; in create_midi2_ump()
733 ep_in->pair = ep_out; in create_midi2_ump()
734 ep_in->rmidi = rmidi; in create_midi2_ump()
735 ep_in->ump = ump; in create_midi2_ump()
738 ep_out->pair = ep_in; in create_midi2_ump()
739 ep_out->rmidi = rmidi; in create_midi2_ump()
740 ep_out->ump = ump; in create_midi2_ump()
743 list_add_tail(&rmidi->list, &umidi->rawmidi_list); in create_midi2_ump()
753 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) { in find_midi2_ump()
754 if (rmidi->usb_block_id == blk_id) in find_midi2_ump()
768 usb_audio_dbg(umidi->chip, "Looking for a pair for EP-in 0x%02x\n", in find_matching_ep_partner()
769 ep->endpoint); in find_matching_ep_partner()
770 list_for_each_entry(pair_ep, &umidi->ep_list, list) { in find_matching_ep_partner()
771 if (pair_ep->direction != STR_OUT) in find_matching_ep_partner()
773 if (pair_ep->pair) in find_matching_ep_partner()
775 for (blk = 0; blk < pair_ep->ms_ep->bNumGrpTrmBlock; blk++) { in find_matching_ep_partner()
776 if (pair_ep->ms_ep->baAssoGrpTrmBlkID[blk] == blk_id) { in find_matching_ep_partner()
777 usb_audio_dbg(umidi->chip, in find_matching_ep_partner()
778 "Found a match with EP-out 0x%02x blk %d\n", in find_matching_ep_partner()
779 pair_ep->endpoint, blk); in find_matching_ep_partner()
788 * this needs to be called after starting the input streams for bi-directional
796 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) { in parse_ump_endpoints()
797 if (!rmidi->ump || in parse_ump_endpoints()
798 !(rmidi->ump->core.info_flags & SNDRV_RAWMIDI_INFO_DUPLEX)) in parse_ump_endpoints()
800 err = snd_ump_parse_endpoint(rmidi->ump); in parse_ump_endpoints()
802 rmidi->ump_parsed = true; in parse_ump_endpoints()
804 if (err == -ENOMEM) in parse_ump_endpoints()
815 struct snd_usb_midi2_interface *umidi = rmidi->umidi; in create_gtb_block()
824 usb_audio_dbg(umidi->chip, in create_gtb_block()
826 blk, desc->bGrpTrmBlkType, desc->nGroupTrm, in create_gtb_block()
827 desc->nNumGroupTrm, desc->bMIDIProtocol, in create_gtb_block()
828 __le16_to_cpu(desc->wMaxInputBandwidth), in create_gtb_block()
829 __le16_to_cpu(desc->wMaxOutputBandwidth)); in create_gtb_block()
832 switch (desc->bGrpTrmBlkType) { in create_gtb_block()
843 usb_audio_dbg(umidi->chip, "Unsupported GTB type %d\n", in create_gtb_block()
844 desc->bGrpTrmBlkType); in create_gtb_block()
848 /* guess work: set blk-1 as the (0-based) block ID */ in create_gtb_block()
849 err = snd_ump_block_new(rmidi->ump, blk - 1, type, in create_gtb_block()
850 desc->nGroupTrm, desc->nNumGroupTrm, in create_gtb_block()
852 if (err == -EBUSY) in create_gtb_block()
857 if (desc->iBlockItem) in create_gtb_block()
858 usb_string(rmidi->dev, desc->iBlockItem, in create_gtb_block()
859 fb->info.name, sizeof(fb->info.name)); in create_gtb_block()
861 if (__le16_to_cpu(desc->wMaxInputBandwidth) == 1 || in create_gtb_block()
862 __le16_to_cpu(desc->wMaxOutputBandwidth) == 1) in create_gtb_block()
863 fb->info.flags |= SNDRV_UMP_BLOCK_IS_MIDI1 | in create_gtb_block()
866 /* if MIDI 2.0 protocol is supported and yet the GTB shows MIDI 1.0, in create_gtb_block()
867 * treat it as a MIDI 1.0-specific block in create_gtb_block()
869 if (rmidi->ump->info.protocol_caps & SNDRV_UMP_EP_INFO_PROTO_MIDI2) { in create_gtb_block()
870 switch (desc->bMIDIProtocol) { in create_gtb_block()
875 fb->info.flags |= SNDRV_UMP_BLOCK_IS_MIDI1; in create_gtb_block()
880 snd_ump_update_group_attrs(rmidi->ump); in create_gtb_block()
882 usb_audio_dbg(umidi->chip, in create_gtb_block()
884 blk, fb->info.name, fb->info.flags); in create_gtb_block()
894 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) { in create_blocks_from_gtb()
895 if (!rmidi->ump) in create_blocks_from_gtb()
898 if (rmidi->ump_parsed || rmidi->ump->info.num_blocks) in create_blocks_from_gtb()
900 /* GTB is static-only */ in create_blocks_from_gtb()
901 rmidi->ump->info.flags |= SNDRV_UMP_EP_INFO_STATIC_BLOCKS; in create_blocks_from_gtb()
904 if (!rmidi->eps[dir]) in create_blocks_from_gtb()
906 for (i = 0; i < rmidi->eps[dir]->ms_ep->bNumGrpTrmBlock; i++) { in create_blocks_from_gtb()
907 blk = rmidi->eps[dir]->ms_ep->baAssoGrpTrmBlkID[i]; in create_blocks_from_gtb()
925 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) { in attach_legacy_rawmidi()
926 err = snd_ump_attach_legacy_rawmidi(rmidi->ump, in attach_legacy_rawmidi()
927 "Legacy MIDI", in attach_legacy_rawmidi()
928 umidi->chip->num_rawmidis); in attach_legacy_rawmidi()
931 umidi->chip->num_rawmidis++; in attach_legacy_rawmidi()
941 list_del(&umidi->list); in snd_usb_midi_v2_free()
942 kfree(umidi->blk_descs); in snd_usb_midi_v2_free()
946 /* parse the interface for MIDI 2.0 */
952 /* First, create an object for each USB MIDI Endpoint */ in parse_midi_2_0()
956 if (list_empty(&umidi->ep_list)) { in parse_midi_2_0()
957 usb_audio_warn(umidi->chip, "No MIDI endpoints found\n"); in parse_midi_2_0()
958 return -ENODEV; in parse_midi_2_0()
966 list_for_each_entry(ep, &umidi->ep_list, list) { in parse_midi_2_0()
968 if (ep->direction != STR_IN) in parse_midi_2_0()
970 for (blk = 0; blk < ep->ms_ep->bNumGrpTrmBlock; blk++) { in parse_midi_2_0()
971 id = ep->ms_ep->baAssoGrpTrmBlkID[blk]; in parse_midi_2_0()
982 list_for_each_entry(ep, &umidi->ep_list, list) { in parse_midi_2_0()
983 if (ep->rmidi) in parse_midi_2_0()
985 for (blk = 0; blk < ep->ms_ep->bNumGrpTrmBlock; blk++) { in parse_midi_2_0()
986 id = ep->ms_ep->baAssoGrpTrmBlkID[blk]; in parse_midi_2_0()
989 usb_audio_dbg(umidi->chip, in parse_midi_2_0()
991 ep->endpoint, id); in parse_midi_2_0()
992 if (ep->direction == STR_IN) in parse_midi_2_0()
1005 /* is the given interface for MIDI 2.0? */
1009 (struct usb_ms_header_descriptor *)hostif->extra; in is_midi2_altset()
1011 if (hostif->extralen < 7 || in is_midi2_altset()
1012 ms_header->bLength < 7 || in is_midi2_altset()
1013 ms_header->bDescriptorType != USB_DT_CS_INTERFACE || in is_midi2_altset()
1014 ms_header->bDescriptorSubtype != UAC_HEADER) in is_midi2_altset()
1017 return le16_to_cpu(ms_header->bcdMSC) == USB_MS_REV_MIDI_2_0; in is_midi2_altset()
1023 usb_audio_dbg(umidi->chip, "Setting host iface %d:%d\n", in set_altset()
1024 umidi->hostif->desc.bInterfaceNumber, in set_altset()
1025 umidi->hostif->desc.bAlternateSetting); in set_altset()
1026 return usb_set_interface(umidi->chip->dev, in set_altset()
1027 umidi->hostif->desc.bInterfaceNumber, in set_altset()
1028 umidi->hostif->desc.bAlternateSetting); in set_altset()
1037 usb_string(dev, id, ump->info.name, sizeof(ump->info.name)); in fill_ump_ep_name()
1039 /* trim superfluous "MIDI" suffix */ in fill_ump_ep_name()
1040 len = strlen(ump->info.name); in fill_ump_ep_name()
1041 if (len > 5 && !strcmp(ump->info.name + len - 5, " MIDI")) in fill_ump_ep_name()
1042 ump->info.name[len - 5] = 0; in fill_ump_ep_name()
1048 struct usb_device *dev = umidi->chip->dev; in set_fallback_rawmidi_names()
1052 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) { in set_fallback_rawmidi_names()
1053 ump = rmidi->ump; in set_fallback_rawmidi_names()
1055 if (!*ump->info.name && umidi->hostif->desc.iInterface) in set_fallback_rawmidi_names()
1056 fill_ump_ep_name(ump, dev, umidi->hostif->desc.iInterface); in set_fallback_rawmidi_names()
1057 else if (!*ump->info.name && dev->descriptor.iProduct) in set_fallback_rawmidi_names()
1058 fill_ump_ep_name(ump, dev, dev->descriptor.iProduct); in set_fallback_rawmidi_names()
1060 if (!*ump->info.name) in set_fallback_rawmidi_names()
1061 sprintf(ump->info.name, "USB MIDI %d", rmidi->index); in set_fallback_rawmidi_names()
1063 if (!*ump->core.name) in set_fallback_rawmidi_names()
1064 strscpy(ump->core.name, ump->info.name, in set_fallback_rawmidi_names()
1065 sizeof(ump->core.name)); in set_fallback_rawmidi_names()
1066 /* use serial number string as unique UMP product id */ in set_fallback_rawmidi_names()
1067 if (!*ump->info.product_id && dev->descriptor.iSerialNumber) in set_fallback_rawmidi_names()
1068 usb_string(dev, dev->descriptor.iSerialNumber, in set_fallback_rawmidi_names()
1069 ump->info.product_id, in set_fallback_rawmidi_names()
1070 sizeof(ump->info.product_id)); in set_fallback_rawmidi_names()
1074 /* create MIDI interface; fallback to MIDI 1.0 if needed */
1085 iface->altsetting[0].desc.bInterfaceNumber); in snd_usb_midi_v2_create()
1087 /* fallback to MIDI 1.0? */ in snd_usb_midi_v2_create()
1089 usb_audio_info(chip, "Falling back to MIDI 1.0 by module option\n"); in snd_usb_midi_v2_create()
1092 if ((quirk && quirk->type != QUIRK_MIDI_STANDARD_INTERFACE) || in snd_usb_midi_v2_create()
1093 iface->num_altsetting < 2) { in snd_usb_midi_v2_create()
1094 usb_audio_info(chip, "Quirk or no altset; falling back to MIDI 1.0\n"); in snd_usb_midi_v2_create()
1097 hostif = &iface->altsetting[1]; in snd_usb_midi_v2_create()
1099 usb_audio_info(chip, "No MIDI 2.0 at altset 1, falling back to MIDI 1.0\n"); in snd_usb_midi_v2_create()
1102 if (!hostif->desc.bNumEndpoints) { in snd_usb_midi_v2_create()
1103 usb_audio_info(chip, "No endpoint at altset 1, falling back to MIDI 1.0\n"); in snd_usb_midi_v2_create()
1107 usb_audio_dbg(chip, "Creating a MIDI 2.0 instance for %d:%d\n", in snd_usb_midi_v2_create()
1108 hostif->desc.bInterfaceNumber, in snd_usb_midi_v2_create()
1109 hostif->desc.bAlternateSetting); in snd_usb_midi_v2_create()
1113 return -ENOMEM; in snd_usb_midi_v2_create()
1114 umidi->chip = chip; in snd_usb_midi_v2_create()
1115 umidi->iface = iface; in snd_usb_midi_v2_create()
1116 umidi->hostif = hostif; in snd_usb_midi_v2_create()
1117 INIT_LIST_HEAD(&umidi->rawmidi_list); in snd_usb_midi_v2_create()
1118 INIT_LIST_HEAD(&umidi->ep_list); in snd_usb_midi_v2_create()
1120 list_add_tail(&umidi->list, &chip->midi_v2_list); in snd_usb_midi_v2_create()
1128 /* assume only altset 1 corresponding to MIDI 2.0 interface */ in snd_usb_midi_v2_create()
1131 usb_audio_err(chip, "Failed to parse MIDI 2.0 interface\n"); in snd_usb_midi_v2_create()
1177 return __snd_usbmidi_create(chip->card, iface, &chip->midi_list, in snd_usb_midi_v2_create()
1178 quirk, usb_id, &chip->num_rawmidis); in snd_usb_midi_v2_create()
1192 list_for_each_entry(umidi, &chip->midi_v2_list, list) { in snd_usb_midi_v2_suspend_all()
1193 list_for_each_entry(ep, &umidi->ep_list, list) in snd_usb_midi_v2_suspend_all()
1200 ep->running = ep->suspended; in resume_midi2_endpoint()
1201 if (ep->direction == STR_IN) in resume_midi2_endpoint()
1211 list_for_each_entry(umidi, &chip->midi_v2_list, list) { in snd_usb_midi_v2_resume_all()
1213 list_for_each_entry(ep, &umidi->ep_list, list) in snd_usb_midi_v2_resume_all()
1223 list_for_each_entry(umidi, &chip->midi_v2_list, list) { in snd_usb_midi_v2_disconnect_all()
1224 umidi->disconnected = 1; in snd_usb_midi_v2_disconnect_all()
1225 list_for_each_entry(ep, &umidi->ep_list, list) { in snd_usb_midi_v2_disconnect_all()
1226 ep->disconnected = 1; in snd_usb_midi_v2_disconnect_all()
1233 /* release the MIDI instance */
1238 list_for_each_entry_safe(umidi, next, &chip->midi_v2_list, list) in snd_usb_midi_v2_free_all()