1241 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * MIDI 2.0 support4 */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 26static bool midi2_enable = true;27module_param(midi2_enable, bool, 0444);28MODULE_PARM_DESC(midi2_enable, "Enable MIDI 2.0 support.");29 30static bool midi2_ump_probe = true;31module_param(midi2_ump_probe, bool, 0444);32MODULE_PARM_DESC(midi2_ump_probe, "Probe UMP v1.1 support at first.");33 34/* stream direction; just shorter names */35enum {36 STR_OUT = SNDRV_RAWMIDI_STREAM_OUTPUT,37 STR_IN = SNDRV_RAWMIDI_STREAM_INPUT38};39 40#define NUM_URBS 841 42struct snd_usb_midi2_urb;43struct snd_usb_midi2_endpoint;44struct snd_usb_midi2_ump;45struct snd_usb_midi2_interface;46 47/* URB context */48struct 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 */55struct 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 */80struct 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 */92struct 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 */105static 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 */137static 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 153static 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 */159static 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 */175static 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 182static 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 */188static 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 */215static 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 else225 submit_output_urbs_locked(ep);226 spin_unlock_irqrestore(&ep->lock, flags);227}228 229/* kill URBs for close, suspend and disconnect */230static 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 */247static 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 */261static 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() */283static 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 else296 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 else320 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 335static struct snd_usb_midi2_endpoint *336ump_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 */344static 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 */364static 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 */376static 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 */387static 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 */395static 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 424static 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 */432static 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 else459 ep->interval = 0;460 if (dir == STR_IN) {461 if (ep->interval)462 ep->pipe = usb_rcvintpipe(ep->dev, endpoint);463 else464 ep->pipe = usb_rcvbulkpipe(ep->dev, endpoint);465 } else {466 if (ep->interval)467 ep->pipe = usb_sndintpipe(ep->dev, endpoint);468 else469 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() */478static 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 */486static 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 */498static 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 */521static 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 */564static const struct usb_ms20_gr_trm_block_descriptor *565find_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 */588static 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)611 ump->info.protocol = protocol;612 613 protocol_caps = protocol;614 switch (desc->bMIDIProtocol) {615 case USB_MS_MIDI_PROTO_1_0_64_JRTS:616 case USB_MS_MIDI_PROTO_1_0_128_JRTS:617 case USB_MS_MIDI_PROTO_2_0_JRTS:618 protocol_caps |= SNDRV_UMP_EP_INFO_PROTO_JRTS_TX |619 SNDRV_UMP_EP_INFO_PROTO_JRTS_RX;620 break;621 }622 623 ump->info.protocol_caps |= protocol_caps;624 return 0;625}626 627/* allocate and parse for each assigned group terminal block */628static int parse_group_terminal_blocks(struct snd_usb_midi2_interface *umidi)629{630 struct snd_usb_midi2_ump *rmidi;631 const struct usb_ms20_gr_trm_block_descriptor *desc;632 int err;633 634 err = get_group_terminal_block_descs(umidi);635 if (err < 0)636 return err;637 if (!umidi->blk_descs)638 return 0;639 640 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {641 desc = find_group_terminal_block(umidi, rmidi->usb_block_id);642 if (!desc)643 continue;644 err = parse_group_terminal_block(rmidi, desc);645 if (err < 0)646 return err;647 }648 649 return 0;650}651 652/* parse endpoints included in the given interface and create objects */653static int parse_midi_2_0_endpoints(struct snd_usb_midi2_interface *umidi)654{655 struct usb_host_interface *hostif = umidi->hostif;656 struct usb_host_endpoint *hostep;657 struct usb_ms20_endpoint_descriptor *ms_ep;658 int i, err;659 660 for (i = 0; i < hostif->desc.bNumEndpoints; i++) {661 hostep = &hostif->endpoint[i];662 if (!usb_endpoint_xfer_bulk(&hostep->desc) &&663 !usb_endpoint_xfer_int(&hostep->desc))664 continue;665 ms_ep = find_usb_ms_endpoint_descriptor(hostep, USB_MS_GENERAL_2_0);666 if (!ms_ep)667 continue;668 if (ms_ep->bLength <= sizeof(*ms_ep))669 continue;670 if (!ms_ep->bNumGrpTrmBlock)671 continue;672 if (ms_ep->bLength < sizeof(*ms_ep) + ms_ep->bNumGrpTrmBlock)673 continue;674 err = create_midi2_endpoint(umidi, hostep, ms_ep);675 if (err < 0)676 return err;677 }678 return 0;679}680 681static void free_all_midi2_umps(struct snd_usb_midi2_interface *umidi)682{683 struct snd_usb_midi2_ump *rmidi;684 685 while (!list_empty(&umidi->rawmidi_list)) {686 rmidi = list_first_entry(&umidi->rawmidi_list,687 struct snd_usb_midi2_ump, list);688 list_del(&rmidi->list);689 kfree(rmidi);690 }691}692 693static int create_midi2_ump(struct snd_usb_midi2_interface *umidi,694 struct snd_usb_midi2_endpoint *ep_in,695 struct snd_usb_midi2_endpoint *ep_out,696 int blk_id)697{698 struct snd_usb_midi2_ump *rmidi;699 struct snd_ump_endpoint *ump;700 int input, output;701 char idstr[16];702 int err;703 704 rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);705 if (!rmidi)706 return -ENOMEM;707 INIT_LIST_HEAD(&rmidi->list);708 rmidi->dev = umidi->chip->dev;709 rmidi->umidi = umidi;710 rmidi->usb_block_id = blk_id;711 712 rmidi->index = umidi->chip->num_rawmidis;713 snprintf(idstr, sizeof(idstr), "UMP %d", rmidi->index);714 input = ep_in ? 1 : 0;715 output = ep_out ? 1 : 0;716 err = snd_ump_endpoint_new(umidi->chip->card, idstr, rmidi->index,717 output, input, &ump);718 if (err < 0) {719 usb_audio_dbg(umidi->chip, "Failed to create a UMP object\n");720 kfree(rmidi);721 return err;722 }723 724 rmidi->ump = ump;725 umidi->chip->num_rawmidis++;726 727 ump->private_data = rmidi;728 ump->ops = &snd_usb_midi_v2_ump_ops;729 730 rmidi->eps[STR_IN] = ep_in;731 rmidi->eps[STR_OUT] = ep_out;732 if (ep_in) {733 ep_in->pair = ep_out;734 ep_in->rmidi = rmidi;735 ep_in->ump = ump;736 }737 if (ep_out) {738 ep_out->pair = ep_in;739 ep_out->rmidi = rmidi;740 ep_out->ump = ump;741 }742 743 list_add_tail(&rmidi->list, &umidi->rawmidi_list);744 return 0;745}746 747/* find the UMP EP with the given USB block id */748static struct snd_usb_midi2_ump *749find_midi2_ump(struct snd_usb_midi2_interface *umidi, int blk_id)750{751 struct snd_usb_midi2_ump *rmidi;752 753 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {754 if (rmidi->usb_block_id == blk_id)755 return rmidi;756 }757 return NULL;758}759 760/* look for the matching output endpoint and create UMP object if found */761static int find_matching_ep_partner(struct snd_usb_midi2_interface *umidi,762 struct snd_usb_midi2_endpoint *ep,763 int blk_id)764{765 struct snd_usb_midi2_endpoint *pair_ep;766 int blk;767 768 usb_audio_dbg(umidi->chip, "Looking for a pair for EP-in 0x%02x\n",769 ep->endpoint);770 list_for_each_entry(pair_ep, &umidi->ep_list, list) {771 if (pair_ep->direction != STR_OUT)772 continue;773 if (pair_ep->pair)774 continue; /* already paired */775 for (blk = 0; blk < pair_ep->ms_ep->bNumGrpTrmBlock; blk++) {776 if (pair_ep->ms_ep->baAssoGrpTrmBlkID[blk] == blk_id) {777 usb_audio_dbg(umidi->chip,778 "Found a match with EP-out 0x%02x blk %d\n",779 pair_ep->endpoint, blk);780 return create_midi2_ump(umidi, ep, pair_ep, blk_id);781 }782 }783 }784 return 0;785}786 787/* Call UMP helper to parse UMP endpoints;788 * this needs to be called after starting the input streams for bi-directional789 * communications790 */791static int parse_ump_endpoints(struct snd_usb_midi2_interface *umidi)792{793 struct snd_usb_midi2_ump *rmidi;794 int err;795 796 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {797 if (!rmidi->ump ||798 !(rmidi->ump->core.info_flags & SNDRV_RAWMIDI_INFO_DUPLEX))799 continue;800 err = snd_ump_parse_endpoint(rmidi->ump);801 if (!err) {802 rmidi->ump_parsed = true;803 } else {804 if (err == -ENOMEM)805 return err;806 /* fall back to GTB later */807 }808 }809 return 0;810}811 812/* create a UMP block from a GTB entry */813static int create_gtb_block(struct snd_usb_midi2_ump *rmidi, int dir, int blk)814{815 struct snd_usb_midi2_interface *umidi = rmidi->umidi;816 const struct usb_ms20_gr_trm_block_descriptor *desc;817 struct snd_ump_block *fb;818 int type, err;819 820 desc = find_group_terminal_block(umidi, blk);821 if (!desc)822 return 0;823 824 usb_audio_dbg(umidi->chip,825 "GTB %d: type=%d, group=%d/%d, protocol=%d, in bw=%d, out bw=%d\n",826 blk, desc->bGrpTrmBlkType, desc->nGroupTrm,827 desc->nNumGroupTrm, desc->bMIDIProtocol,828 __le16_to_cpu(desc->wMaxInputBandwidth),829 __le16_to_cpu(desc->wMaxOutputBandwidth));830 831 /* assign the direction */832 switch (desc->bGrpTrmBlkType) {833 case USB_MS_GR_TRM_BLOCK_TYPE_BIDIRECTIONAL:834 type = SNDRV_UMP_DIR_BIDIRECTION;835 break;836 case USB_MS_GR_TRM_BLOCK_TYPE_INPUT_ONLY:837 type = SNDRV_UMP_DIR_INPUT;838 break;839 case USB_MS_GR_TRM_BLOCK_TYPE_OUTPUT_ONLY:840 type = SNDRV_UMP_DIR_OUTPUT;841 break;842 default:843 usb_audio_dbg(umidi->chip, "Unsupported GTB type %d\n",844 desc->bGrpTrmBlkType);845 return 0; /* unsupported */846 }847 848 /* guess work: set blk-1 as the (0-based) block ID */849 err = snd_ump_block_new(rmidi->ump, blk - 1, type,850 desc->nGroupTrm, desc->nNumGroupTrm,851 &fb);852 if (err == -EBUSY)853 return 0; /* already present */854 else if (err)855 return err;856 857 if (desc->iBlockItem)858 usb_string(rmidi->dev, desc->iBlockItem,859 fb->info.name, sizeof(fb->info.name));860 861 if (__le16_to_cpu(desc->wMaxInputBandwidth) == 1 ||862 __le16_to_cpu(desc->wMaxOutputBandwidth) == 1)863 fb->info.flags |= SNDRV_UMP_BLOCK_IS_MIDI1 |864 SNDRV_UMP_BLOCK_IS_LOWSPEED;865 866 /* if MIDI 2.0 protocol is supported and yet the GTB shows MIDI 1.0,867 * treat it as a MIDI 1.0-specific block868 */869 if (rmidi->ump->info.protocol_caps & SNDRV_UMP_EP_INFO_PROTO_MIDI2) {870 switch (desc->bMIDIProtocol) {871 case USB_MS_MIDI_PROTO_1_0_64:872 case USB_MS_MIDI_PROTO_1_0_64_JRTS:873 case USB_MS_MIDI_PROTO_1_0_128:874 case USB_MS_MIDI_PROTO_1_0_128_JRTS:875 fb->info.flags |= SNDRV_UMP_BLOCK_IS_MIDI1;876 break;877 }878 }879 880 snd_ump_update_group_attrs(rmidi->ump);881 882 usb_audio_dbg(umidi->chip,883 "Created a UMP block %d from GTB, name=%s, flags=0x%x\n",884 blk, fb->info.name, fb->info.flags);885 return 0;886}887 888/* Create UMP blocks for each UMP EP */889static int create_blocks_from_gtb(struct snd_usb_midi2_interface *umidi)890{891 struct snd_usb_midi2_ump *rmidi;892 int i, blk, err, dir;893 894 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {895 if (!rmidi->ump)896 continue;897 /* Blocks have been already created? */898 if (rmidi->ump_parsed || rmidi->ump->info.num_blocks)899 continue;900 /* GTB is static-only */901 rmidi->ump->info.flags |= SNDRV_UMP_EP_INFO_STATIC_BLOCKS;902 /* loop over GTBs */903 for (dir = 0; dir < 2; dir++) {904 if (!rmidi->eps[dir])905 continue;906 for (i = 0; i < rmidi->eps[dir]->ms_ep->bNumGrpTrmBlock; i++) {907 blk = rmidi->eps[dir]->ms_ep->baAssoGrpTrmBlkID[i];908 err = create_gtb_block(rmidi, dir, blk);909 if (err < 0)910 return err;911 }912 }913 }914 915 return 0;916}917 918/* attach legacy rawmidis */919static int attach_legacy_rawmidi(struct snd_usb_midi2_interface *umidi)920{921#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)922 struct snd_usb_midi2_ump *rmidi;923 int err;924 925 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {926 err = snd_ump_attach_legacy_rawmidi(rmidi->ump,927 "Legacy MIDI",928 umidi->chip->num_rawmidis);929 if (err < 0)930 return err;931 umidi->chip->num_rawmidis++;932 }933#endif934 return 0;935}936 937static void snd_usb_midi_v2_free(struct snd_usb_midi2_interface *umidi)938{939 free_all_midi2_endpoints(umidi);940 free_all_midi2_umps(umidi);941 list_del(&umidi->list);942 kfree(umidi->blk_descs);943 kfree(umidi);944}945 946/* parse the interface for MIDI 2.0 */947static int parse_midi_2_0(struct snd_usb_midi2_interface *umidi)948{949 struct snd_usb_midi2_endpoint *ep;950 int blk, id, err;951 952 /* First, create an object for each USB MIDI Endpoint */953 err = parse_midi_2_0_endpoints(umidi);954 if (err < 0)955 return err;956 if (list_empty(&umidi->ep_list)) {957 usb_audio_warn(umidi->chip, "No MIDI endpoints found\n");958 return -ENODEV;959 }960 961 /*962 * Next, look for EP I/O pairs that are found in group terminal blocks963 * A UMP object is created for each EP I/O pair as bidirecitonal964 * UMP EP965 */966 list_for_each_entry(ep, &umidi->ep_list, list) {967 /* only input in this loop; output is matched in find_midi_ump() */968 if (ep->direction != STR_IN)969 continue;970 for (blk = 0; blk < ep->ms_ep->bNumGrpTrmBlock; blk++) {971 id = ep->ms_ep->baAssoGrpTrmBlkID[blk];972 err = find_matching_ep_partner(umidi, ep, id);973 if (err < 0)974 return err;975 }976 }977 978 /*979 * For the remaining EPs, treat as singles, create a UMP object with980 * unidirectional EP981 */982 list_for_each_entry(ep, &umidi->ep_list, list) {983 if (ep->rmidi)984 continue; /* already paired */985 for (blk = 0; blk < ep->ms_ep->bNumGrpTrmBlock; blk++) {986 id = ep->ms_ep->baAssoGrpTrmBlkID[blk];987 if (find_midi2_ump(umidi, id))988 continue;989 usb_audio_dbg(umidi->chip,990 "Creating a unidirection UMP for EP=0x%02x, blk=%d\n",991 ep->endpoint, id);992 if (ep->direction == STR_IN)993 err = create_midi2_ump(umidi, ep, NULL, id);994 else995 err = create_midi2_ump(umidi, NULL, ep, id);996 if (err < 0)997 return err;998 break;999 }1000 }1001 1002 return 0;1003}1004 1005/* is the given interface for MIDI 2.0? */1006static bool is_midi2_altset(struct usb_host_interface *hostif)1007{1008 struct usb_ms_header_descriptor *ms_header =1009 (struct usb_ms_header_descriptor *)hostif->extra;1010 1011 if (hostif->extralen < 7 ||1012 ms_header->bLength < 7 ||1013 ms_header->bDescriptorType != USB_DT_CS_INTERFACE ||1014 ms_header->bDescriptorSubtype != UAC_HEADER)1015 return false;1016 1017 return le16_to_cpu(ms_header->bcdMSC) == USB_MS_REV_MIDI_2_0;1018}1019 1020/* change the altsetting */1021static int set_altset(struct snd_usb_midi2_interface *umidi)1022{1023 usb_audio_dbg(umidi->chip, "Setting host iface %d:%d\n",1024 umidi->hostif->desc.bInterfaceNumber,1025 umidi->hostif->desc.bAlternateSetting);1026 return usb_set_interface(umidi->chip->dev,1027 umidi->hostif->desc.bInterfaceNumber,1028 umidi->hostif->desc.bAlternateSetting);1029}1030 1031/* fill UMP Endpoint name string from USB descriptor */1032static void fill_ump_ep_name(struct snd_ump_endpoint *ump,1033 struct usb_device *dev, int id)1034{1035 int len;1036 1037 usb_string(dev, id, ump->info.name, sizeof(ump->info.name));1038 1039 /* trim superfluous "MIDI" suffix */1040 len = strlen(ump->info.name);1041 if (len > 5 && !strcmp(ump->info.name + len - 5, " MIDI"))1042 ump->info.name[len - 5] = 0;1043}1044 1045/* fill the fallback name string for each rawmidi instance */1046static void set_fallback_rawmidi_names(struct snd_usb_midi2_interface *umidi)1047{1048 struct usb_device *dev = umidi->chip->dev;1049 struct snd_usb_midi2_ump *rmidi;1050 struct snd_ump_endpoint *ump;1051 1052 list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {1053 ump = rmidi->ump;1054 /* fill UMP EP name from USB descriptors */1055 if (!*ump->info.name && umidi->hostif->desc.iInterface)1056 fill_ump_ep_name(ump, dev, umidi->hostif->desc.iInterface);1057 else if (!*ump->info.name && dev->descriptor.iProduct)1058 fill_ump_ep_name(ump, dev, dev->descriptor.iProduct);1059 /* fill fallback name */1060 if (!*ump->info.name)1061 sprintf(ump->info.name, "USB MIDI %d", rmidi->index);1062 /* copy as rawmidi name if not set */1063 if (!*ump->core.name)1064 strscpy(ump->core.name, ump->info.name,1065 sizeof(ump->core.name));1066 /* use serial number string as unique UMP product id */1067 if (!*ump->info.product_id && dev->descriptor.iSerialNumber)1068 usb_string(dev, dev->descriptor.iSerialNumber,1069 ump->info.product_id,1070 sizeof(ump->info.product_id));1071 }1072}1073 1074/* create MIDI interface; fallback to MIDI 1.0 if needed */1075int snd_usb_midi_v2_create(struct snd_usb_audio *chip,1076 struct usb_interface *iface,1077 const struct snd_usb_audio_quirk *quirk,1078 unsigned int usb_id)1079{1080 struct snd_usb_midi2_interface *umidi;1081 struct usb_host_interface *hostif;1082 int err;1083 1084 usb_audio_dbg(chip, "Parsing interface %d...\n",1085 iface->altsetting[0].desc.bInterfaceNumber);1086 1087 /* fallback to MIDI 1.0? */1088 if (!midi2_enable) {1089 usb_audio_info(chip, "Falling back to MIDI 1.0 by module option\n");1090 goto fallback_to_midi1;1091 }1092 if ((quirk && quirk->type != QUIRK_MIDI_STANDARD_INTERFACE) ||1093 iface->num_altsetting < 2) {1094 usb_audio_info(chip, "Quirk or no altset; falling back to MIDI 1.0\n");1095 goto fallback_to_midi1;1096 }1097 hostif = &iface->altsetting[1];1098 if (!is_midi2_altset(hostif)) {1099 usb_audio_info(chip, "No MIDI 2.0 at altset 1, falling back to MIDI 1.0\n");1100 goto fallback_to_midi1;1101 }1102 if (!hostif->desc.bNumEndpoints) {1103 usb_audio_info(chip, "No endpoint at altset 1, falling back to MIDI 1.0\n");1104 goto fallback_to_midi1;1105 }1106 1107 usb_audio_dbg(chip, "Creating a MIDI 2.0 instance for %d:%d\n",1108 hostif->desc.bInterfaceNumber,1109 hostif->desc.bAlternateSetting);1110 1111 umidi = kzalloc(sizeof(*umidi), GFP_KERNEL);1112 if (!umidi)1113 return -ENOMEM;1114 umidi->chip = chip;1115 umidi->iface = iface;1116 umidi->hostif = hostif;1117 INIT_LIST_HEAD(&umidi->rawmidi_list);1118 INIT_LIST_HEAD(&umidi->ep_list);1119 1120 list_add_tail(&umidi->list, &chip->midi_v2_list);1121 1122 err = set_altset(umidi);1123 if (err < 0) {1124 usb_audio_err(chip, "Failed to set altset\n");1125 goto error;1126 }1127 1128 /* assume only altset 1 corresponding to MIDI 2.0 interface */1129 err = parse_midi_2_0(umidi);1130 if (err < 0) {1131 usb_audio_err(chip, "Failed to parse MIDI 2.0 interface\n");1132 goto error;1133 }1134 1135 /* parse USB group terminal blocks */1136 err = parse_group_terminal_blocks(umidi);1137 if (err < 0) {1138 usb_audio_err(chip, "Failed to parse GTB\n");1139 goto error;1140 }1141 1142 err = start_input_streams(umidi);1143 if (err < 0) {1144 usb_audio_err(chip, "Failed to start input streams\n");1145 goto error;1146 }1147 1148 if (midi2_ump_probe) {1149 err = parse_ump_endpoints(umidi);1150 if (err < 0) {1151 usb_audio_err(chip, "Failed to parse UMP endpoint\n");1152 goto error;1153 }1154 }1155 1156 err = create_blocks_from_gtb(umidi);1157 if (err < 0) {1158 usb_audio_err(chip, "Failed to create GTB blocks\n");1159 goto error;1160 }1161 1162 set_fallback_rawmidi_names(umidi);1163 1164 err = attach_legacy_rawmidi(umidi);1165 if (err < 0) {1166 usb_audio_err(chip, "Failed to create legacy rawmidi\n");1167 goto error;1168 }1169 1170 return 0;1171 1172 error:1173 snd_usb_midi_v2_free(umidi);1174 return err;1175 1176 fallback_to_midi1:1177 return __snd_usbmidi_create(chip->card, iface, &chip->midi_list,1178 quirk, usb_id, &chip->num_rawmidis);1179}1180 1181static void suspend_midi2_endpoint(struct snd_usb_midi2_endpoint *ep)1182{1183 kill_midi_urbs(ep, true);1184 drain_urb_queue(ep);1185}1186 1187void snd_usb_midi_v2_suspend_all(struct snd_usb_audio *chip)1188{1189 struct snd_usb_midi2_interface *umidi;1190 struct snd_usb_midi2_endpoint *ep;1191 1192 list_for_each_entry(umidi, &chip->midi_v2_list, list) {1193 list_for_each_entry(ep, &umidi->ep_list, list)1194 suspend_midi2_endpoint(ep);1195 }1196}1197 1198static void resume_midi2_endpoint(struct snd_usb_midi2_endpoint *ep)1199{1200 ep->running = ep->suspended;1201 if (ep->direction == STR_IN)1202 submit_io_urbs(ep);1203 /* FIXME: does it all? */1204}1205 1206void snd_usb_midi_v2_resume_all(struct snd_usb_audio *chip)1207{1208 struct snd_usb_midi2_interface *umidi;1209 struct snd_usb_midi2_endpoint *ep;1210 1211 list_for_each_entry(umidi, &chip->midi_v2_list, list) {1212 set_altset(umidi);1213 list_for_each_entry(ep, &umidi->ep_list, list)1214 resume_midi2_endpoint(ep);1215 }1216}1217 1218void snd_usb_midi_v2_disconnect_all(struct snd_usb_audio *chip)1219{1220 struct snd_usb_midi2_interface *umidi;1221 struct snd_usb_midi2_endpoint *ep;1222 1223 list_for_each_entry(umidi, &chip->midi_v2_list, list) {1224 umidi->disconnected = 1;1225 list_for_each_entry(ep, &umidi->ep_list, list) {1226 ep->disconnected = 1;1227 kill_midi_urbs(ep, false);1228 drain_urb_queue(ep);1229 }1230 }1231}1232 1233/* release the MIDI instance */1234void snd_usb_midi_v2_free_all(struct snd_usb_audio *chip)1235{1236 struct snd_usb_midi2_interface *umidi, *next;1237 1238 list_for_each_entry_safe(umidi, next, &chip->midi_v2_list, list)1239 snd_usb_midi_v2_free(umidi);1240}1241