brintos

brintos / linux-shallow public Read only

0
0
Text · 32.8 KiB · 692dfc3 Raw
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