Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7a2f37c authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: gadget: MIDI: Add support for SuperSpeed enumeration"

parents 0a9ca6c6 0d7e0c0f
Loading
Loading
Loading
Loading
+54 −1
Original line number Original line Diff line number Diff line
@@ -167,6 +167,15 @@ static struct usb_endpoint_descriptor bulk_in_desc = {
	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
};
};


static struct usb_ss_ep_comp_descriptor ss_bulk_comp_desc = {
	.bLength =		sizeof(ss_bulk_comp_desc),
	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,

	/* the following 2 values can be tweaked if necessary */
	/* .bMaxBurst =		0, */
	/* .bmAttributes =	0, */
};

/* B.6.2  Class-specific MS Bulk IN Endpoint Descriptor */
/* B.6.2  Class-specific MS Bulk IN Endpoint Descriptor */
static struct usb_ms_endpoint_descriptor_16 ms_in_desc = {
static struct usb_ms_endpoint_descriptor_16 ms_in_desc = {
	/* .bLength =		DYNAMIC */
	/* .bLength =		DYNAMIC */
@@ -720,6 +729,7 @@ fail:
static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
{
{
	struct usb_descriptor_header **midi_function;
	struct usb_descriptor_header **midi_function;
	struct usb_descriptor_header **midi_ss_function;
	struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS];
	struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS];
	struct usb_midi_in_jack_descriptor jack_in_emb_desc[MAX_PORTS];
	struct usb_midi_in_jack_descriptor jack_in_emb_desc[MAX_PORTS];
	struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS];
	struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS];
@@ -727,7 +737,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
	struct usb_composite_dev *cdev = c->cdev;
	struct usb_composite_dev *cdev = c->cdev;
	struct f_midi *midi = func_to_midi(f);
	struct f_midi *midi = func_to_midi(f);
	struct usb_string *us;
	struct usb_string *us;
	int status, n, jack = 1, i = 0;
	int status, n, jack = 1, i = 0, j = 0;


	midi->gadget = cdev->gadget;
	midi->gadget = cdev->gadget;
	tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi);
	tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi);
@@ -767,11 +777,20 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
	if (!midi->out_ep)
	if (!midi->out_ep)
		goto fail;
		goto fail;


	/* allocate temporary function list for ss */
	midi_ss_function = kcalloc((MAX_PORTS * 4) + 11,
				sizeof(*midi_ss_function), GFP_KERNEL);
	if (!midi_ss_function) {
		status = -ENOMEM;
		goto fail;
	}

	/* allocate temporary function list */
	/* allocate temporary function list */
	midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function),
	midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function),
				GFP_KERNEL);
				GFP_KERNEL);
	if (!midi_function) {
	if (!midi_function) {
		status = -ENOMEM;
		status = -ENOMEM;
		kfree(midi_ss_function);
		goto fail;
		goto fail;
	}
	}


@@ -785,6 +804,12 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
	midi_function[i++] = (struct usb_descriptor_header *) &ac_interface_desc;
	midi_function[i++] = (struct usb_descriptor_header *) &ac_interface_desc;
	midi_function[i++] = (struct usb_descriptor_header *) &ac_header_desc;
	midi_function[i++] = (struct usb_descriptor_header *) &ac_header_desc;
	midi_function[i++] = (struct usb_descriptor_header *) &ms_interface_desc;
	midi_function[i++] = (struct usb_descriptor_header *) &ms_interface_desc;
	midi_ss_function[j++] =
			(struct usb_descriptor_header *) &ac_interface_desc;
	midi_ss_function[j++] =
			(struct usb_descriptor_header *) &ac_header_desc;
	midi_ss_function[j++] =
			(struct usb_descriptor_header *) &ms_interface_desc;


	/* calculate the header's wTotalLength */
	/* calculate the header's wTotalLength */
	n = USB_DT_MS_HEADER_SIZE
	n = USB_DT_MS_HEADER_SIZE
@@ -793,6 +818,8 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
	ms_header_desc.wTotalLength = cpu_to_le16(n);
	ms_header_desc.wTotalLength = cpu_to_le16(n);


	midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc;
	midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc;
	midi_ss_function[j++] =
			(struct usb_descriptor_header *) &ms_header_desc;


	/* configure the external IN jacks, each linked to an embedded OUT jack */
	/* configure the external IN jacks, each linked to an embedded OUT jack */
	for (n = 0; n < midi->in_ports; n++) {
	for (n = 0; n < midi->in_ports; n++) {
@@ -806,6 +833,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
		in_ext->bJackID			= jack++;
		in_ext->bJackID			= jack++;
		in_ext->iJack			= 0;
		in_ext->iJack			= 0;
		midi_function[i++] = (struct usb_descriptor_header *) in_ext;
		midi_function[i++] = (struct usb_descriptor_header *) in_ext;
		midi_ss_function[j++] = (struct usb_descriptor_header *) in_ext;


		out_emb->bLength		= USB_DT_MIDI_OUT_SIZE(1);
		out_emb->bLength		= USB_DT_MIDI_OUT_SIZE(1);
		out_emb->bDescriptorType	= USB_DT_CS_INTERFACE;
		out_emb->bDescriptorType	= USB_DT_CS_INTERFACE;
@@ -817,6 +845,8 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
		out_emb->pins[0].baSourceID	= in_ext->bJackID;
		out_emb->pins[0].baSourceID	= in_ext->bJackID;
		out_emb->iJack			= 0;
		out_emb->iJack			= 0;
		midi_function[i++] = (struct usb_descriptor_header *) out_emb;
		midi_function[i++] = (struct usb_descriptor_header *) out_emb;
		midi_ss_function[j++] =
				(struct usb_descriptor_header *) out_emb;


		/* link it to the endpoint */
		/* link it to the endpoint */
		ms_in_desc.baAssocJackID[n] = out_emb->bJackID;
		ms_in_desc.baAssocJackID[n] = out_emb->bJackID;
@@ -834,6 +864,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
		in_emb->bJackID			= jack++;
		in_emb->bJackID			= jack++;
		in_emb->iJack			= 0;
		in_emb->iJack			= 0;
		midi_function[i++] = (struct usb_descriptor_header *) in_emb;
		midi_function[i++] = (struct usb_descriptor_header *) in_emb;
		midi_ss_function[j++] = (struct usb_descriptor_header *) in_emb;


		out_ext->bLength =		USB_DT_MIDI_OUT_SIZE(1);
		out_ext->bLength =		USB_DT_MIDI_OUT_SIZE(1);
		out_ext->bDescriptorType =	USB_DT_CS_INTERFACE;
		out_ext->bDescriptorType =	USB_DT_CS_INTERFACE;
@@ -845,6 +876,8 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
		out_ext->pins[0].baSourceID =	in_emb->bJackID;
		out_ext->pins[0].baSourceID =	in_emb->bJackID;
		out_ext->pins[0].baSourcePin =	1;
		out_ext->pins[0].baSourcePin =	1;
		midi_function[i++] = (struct usb_descriptor_header *) out_ext;
		midi_function[i++] = (struct usb_descriptor_header *) out_ext;
		midi_ss_function[j++] =
				(struct usb_descriptor_header *) out_ext;


		/* link it to the endpoint */
		/* link it to the endpoint */
		ms_out_desc.baAssocJackID[n] = in_emb->bJackID;
		ms_out_desc.baAssocJackID[n] = in_emb->bJackID;
@@ -864,6 +897,16 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
	midi_function[i++] = (struct usb_descriptor_header *) &ms_in_desc;
	midi_function[i++] = (struct usb_descriptor_header *) &ms_in_desc;
	midi_function[i++] = NULL;
	midi_function[i++] = NULL;


	midi_ss_function[j++] = (struct usb_descriptor_header *) &bulk_out_desc;
	midi_ss_function[j++] =
			(struct usb_descriptor_header *) &ss_bulk_comp_desc;
	midi_ss_function[j++] = (struct usb_descriptor_header *) &ms_out_desc;
	midi_ss_function[j++] = (struct usb_descriptor_header *) &bulk_in_desc;
	midi_ss_function[j++] =
			(struct usb_descriptor_header *) &ss_bulk_comp_desc;
	midi_ss_function[j++] = (struct usb_descriptor_header *) &ms_in_desc;
	midi_ss_function[j++] = NULL;

	/*
	/*
	 * support all relevant hardware speeds... we expect that when
	 * support all relevant hardware speeds... we expect that when
	 * hardware is dual speed, all bulk-capable endpoints work at
	 * hardware is dual speed, all bulk-capable endpoints work at
@@ -882,13 +925,23 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
			goto fail_f_midi;
			goto fail_f_midi;
	}
	}


	if (gadget_is_superspeed(c->cdev->gadget)) {
		bulk_in_desc.wMaxPacketSize = cpu_to_le16(1024);
		bulk_out_desc.wMaxPacketSize = cpu_to_le16(1024);
		f->ss_descriptors = usb_copy_descriptors(midi_ss_function);
		if (!f->ss_descriptors)
			goto fail_f_midi;
	}

	kfree(midi_function);
	kfree(midi_function);
	kfree(midi_ss_function);


	return 0;
	return 0;


fail_f_midi:
fail_f_midi:
	kfree(midi_function);
	kfree(midi_function);
	usb_free_descriptors(f->hs_descriptors);
	usb_free_descriptors(f->hs_descriptors);
	kfree(midi_ss_function);
fail:
fail:
	f_midi_unregister_card(midi);
	f_midi_unregister_card(midi);
fail_register:
fail_register: