Lines Matching +full:usb +full:- +full:port +full:- +full:id

1 // SPDX-License-Identifier: GPL-2.0+
3 * f_midi.c -- USB MIDI class function driver
12 * Based on drivers/usb/gadget/f_audio.c,
16 * and drivers/usb/gadget/midi.c,
32 #include <linux/usb/ch9.h>
33 #include <linux/usb/func_utils.h>
34 #include <linux/usb/gadget.h>
35 #include <linux/usb/audio.h>
36 #include <linux/usb/midi.h>
41 MODULE_DESCRIPTION("USB MIDI class function driver");
49 * stored in 4-bit fields. And as the interface currently only holds one
69 * USB -> OUT endpoint -> rawmidi
70 * USB <- IN endpoint <- rawmidi
95 char *id; member
97 /* This fifo is used as a buffer ring for pre-allocated IN usb_requests */
130 /* B.3.2 Class-Specific AC Interface Descriptor */
152 /* B.4.2 Class-Specific MS Interface Descriptor */
176 /* B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor */
200 /* B.6.2 Class-specific MS Bulk IN Endpoint Descriptor */
219 .language = 0x0409, /* en-us */
244 struct f_midi *midi = ep->driver_data; in f_midi_read_data()
245 struct snd_rawmidi_substream *substream = midi->out_substream[cable]; in f_midi_read_data()
248 /* Nobody is listening - throw it on the floor. */ in f_midi_read_data()
251 if (!test_bit(cable, &midi->out_triggered)) in f_midi_read_data()
260 u8 *buf = req->buf; in f_midi_handle_out_data()
262 for (i = 0; i + 3 < req->actual; i += 4) in f_midi_handle_out_data()
273 struct f_midi *midi = ep->driver_data; in f_midi_complete()
274 struct usb_composite_dev *cdev = midi->func.config->cdev; in f_midi_complete()
275 int status = req->status; in f_midi_complete()
279 if (ep == midi->out_ep) { in f_midi_complete()
282 } else if (ep == midi->in_ep) { in f_midi_complete()
285 req->length = 0; in f_midi_complete()
286 queue_work(system_highpri_wq, &midi->work); in f_midi_complete()
292 case -ECONNABORTED: /* hardware forced ep reset */ in f_midi_complete()
293 case -ECONNRESET: /* request dequeued */ in f_midi_complete()
294 case -ESHUTDOWN: /* disconnect from host */ in f_midi_complete()
295 VDBG(cdev, "%s gone (%d), %d/%d\n", ep->name, status, in f_midi_complete()
296 req->actual, req->length); in f_midi_complete()
297 if (ep == midi->out_ep) { in f_midi_complete()
300 * by the midi->in_req_fifo. */ in f_midi_complete()
305 case -EOVERFLOW: /* buffer overrun on read means that in f_midi_complete()
309 DBG(cdev, "%s complete --> %d, %d/%d\n", ep->name, in f_midi_complete()
310 status, req->actual, req->length); in f_midi_complete()
312 case -EREMOTEIO: /* short read */ in f_midi_complete()
318 ERROR(cdev, "kill %s: resubmit %d bytes --> %d\n", in f_midi_complete()
319 ep->name, req->length, status); in f_midi_complete()
329 for (i = 0; i < midi->in_ports; i++) { in f_midi_drop_out_substreams()
330 struct gmidi_in_port *port = midi->in_ports_array + i; in f_midi_drop_out_substreams() local
331 struct snd_rawmidi_substream *substream = port->substream; in f_midi_drop_out_substreams()
333 if (port->active && substream) in f_midi_drop_out_substreams()
343 struct usb_composite_dev *cdev = f->config->cdev; in f_midi_start_ep()
347 err = config_ep_by_speed(midi->gadget, f, ep); in f_midi_start_ep()
349 ERROR(cdev, "can't configure %s: %d\n", ep->name, err); in f_midi_start_ep()
355 ERROR(cdev, "can't start %s: %d\n", ep->name, err); in f_midi_start_ep()
359 ep->driver_data = midi; in f_midi_start_ep()
371 if (intf != midi->ms_id) in f_midi_set_alt()
374 err = f_midi_start_ep(midi, f, midi->in_ep); in f_midi_set_alt()
378 err = f_midi_start_ep(midi, f, midi->out_ep); in f_midi_set_alt()
382 /* pre-allocate write usb requests to use on f_midi_transmit. */ in f_midi_set_alt()
383 while (kfifo_avail(&midi->in_req_fifo)) { in f_midi_set_alt()
385 midi_alloc_ep_req(midi->in_ep, midi->buflen); in f_midi_set_alt()
388 return -ENOMEM; in f_midi_set_alt()
390 req->length = 0; in f_midi_set_alt()
391 req->complete = f_midi_complete; in f_midi_set_alt()
393 kfifo_put(&midi->in_req_fifo, req); in f_midi_set_alt()
397 for (i = 0; i < midi->qlen && err == 0; i++) { in f_midi_set_alt()
399 midi_alloc_ep_req(midi->out_ep, midi->buflen); in f_midi_set_alt()
402 return -ENOMEM; in f_midi_set_alt()
404 req->complete = f_midi_complete; in f_midi_set_alt()
405 err = usb_ep_queue(midi->out_ep, req, GFP_ATOMIC); in f_midi_set_alt()
408 midi->out_ep->name, err); in f_midi_set_alt()
409 if (req->buf != NULL) in f_midi_set_alt()
410 free_ep_req(midi->out_ep, req); in f_midi_set_alt()
421 struct usb_composite_dev *cdev = f->config->cdev; in f_midi_disable()
430 usb_ep_disable(midi->in_ep); in f_midi_disable()
431 usb_ep_disable(midi->out_ep); in f_midi_disable()
434 while (kfifo_get(&midi->in_req_fifo, &req)) in f_midi_disable()
435 free_ep_req(midi->in_ep, req); in f_midi_disable()
446 * Converts MIDI commands to USB MIDI packets.
449 struct gmidi_in_port *port, uint8_t b) in f_midi_transmit_byte() argument
451 uint8_t p[4] = { port->cable << 4, 0, 0, 0 }; in f_midi_transmit_byte()
456 /* System Real-Time Messages */ in f_midi_transmit_byte()
459 next_state = port->state; in f_midi_transmit_byte()
460 port->state = STATE_REAL_TIME; in f_midi_transmit_byte()
465 switch (port->state) { in f_midi_transmit_byte()
473 p[1] = port->data[0]; in f_midi_transmit_byte()
479 p[1] = port->data[0]; in f_midi_transmit_byte()
480 p[2] = port->data[1]; in f_midi_transmit_byte()
486 next_state = port->state; in f_midi_transmit_byte()
487 port->state = STATE_INITIAL; in f_midi_transmit_byte()
493 port->data[0] = port->data[1] = 0; in f_midi_transmit_byte()
494 port->state = STATE_INITIAL; in f_midi_transmit_byte()
497 port->data[0] = b; in f_midi_transmit_byte()
498 port->data[1] = 0; in f_midi_transmit_byte()
503 port->data[0] = b; in f_midi_transmit_byte()
507 port->data[0] = b; in f_midi_transmit_byte()
527 port->data[0] = b; in f_midi_transmit_byte()
528 port->data[1] = 0; in f_midi_transmit_byte()
529 port->state = STATE_INITIAL; in f_midi_transmit_byte()
538 switch (port->state) { in f_midi_transmit_byte()
540 if (port->data[0] < 0xf0) in f_midi_transmit_byte()
541 p[0] |= port->data[0] >> 4; in f_midi_transmit_byte()
545 p[1] = port->data[0]; in f_midi_transmit_byte()
551 port->data[1] = b; in f_midi_transmit_byte()
555 if (port->data[0] < 0xf0) in f_midi_transmit_byte()
556 p[0] |= port->data[0] >> 4; in f_midi_transmit_byte()
560 p[1] = port->data[0]; in f_midi_transmit_byte()
561 p[2] = port->data[1]; in f_midi_transmit_byte()
567 port->data[0] = b; in f_midi_transmit_byte()
571 port->data[1] = b; in f_midi_transmit_byte()
576 p[1] = port->data[0]; in f_midi_transmit_byte()
577 p[2] = port->data[1]; in f_midi_transmit_byte()
585 /* States where we have to write into the USB request */ in f_midi_transmit_byte()
587 port->state == STATE_SYSEX_2 || in f_midi_transmit_byte()
588 port->state == STATE_1PARAM || in f_midi_transmit_byte()
589 port->state == STATE_2PARAM_2 || in f_midi_transmit_byte()
590 port->state == STATE_REAL_TIME) { in f_midi_transmit_byte()
592 unsigned int length = req->length; in f_midi_transmit_byte()
593 u8 *buf = (u8 *)req->buf + length; in f_midi_transmit_byte()
596 req->length = length + sizeof(p); in f_midi_transmit_byte()
600 port->data[0] = port->data[1] = 0; in f_midi_transmit_byte()
604 port->state = next_state; in f_midi_transmit_byte()
618 len = kfifo_peek(&midi->in_req_fifo, &req); in f_midi_do_transmit()
620 ERROR(midi, "%s: Couldn't get usb request\n", __func__); in f_midi_do_transmit()
621 return -1; in f_midi_do_transmit()
626 * IMPORTANT: This will cause the user-space rawmidi device to block in f_midi_do_transmit()
627 * until a) usb requests have been completed or b) snd_rawmidi_write() in f_midi_do_transmit()
630 if (req->length > 0) in f_midi_do_transmit()
633 for (i = midi->in_last_port; i < midi->in_ports; ++i) { in f_midi_do_transmit()
634 struct gmidi_in_port *port = midi->in_ports_array + i; in f_midi_do_transmit() local
635 struct snd_rawmidi_substream *substream = port->substream; in f_midi_do_transmit()
637 if (!port->active || !substream) in f_midi_do_transmit()
640 while (req->length + 3 < midi->buflen) { in f_midi_do_transmit()
644 port->active = 0; in f_midi_do_transmit()
647 f_midi_transmit_byte(req, port, b); in f_midi_do_transmit()
650 active = !!port->active; in f_midi_do_transmit()
654 midi->in_last_port = active ? i : 0; in f_midi_do_transmit()
656 if (req->length <= 0) in f_midi_do_transmit()
662 midi->in_ep->name, err); in f_midi_do_transmit()
663 req->length = 0; /* Re-use request next time. */ in f_midi_do_transmit()
666 kfifo_skip(&midi->in_req_fifo); in f_midi_do_transmit()
667 kfifo_put(&midi->in_req_fifo, req); in f_midi_do_transmit()
676 struct usb_ep *ep = midi->in_ep; in f_midi_transmit()
680 /* We only care about USB requests if IN endpoint is enabled */ in f_midi_transmit()
681 if (!ep || !ep->enabled) in f_midi_transmit()
684 spin_lock_irqsave(&midi->transmit_lock, flags); in f_midi_transmit()
689 spin_unlock_irqrestore(&midi->transmit_lock, flags); in f_midi_transmit()
694 spin_unlock_irqrestore(&midi->transmit_lock, flags); in f_midi_transmit()
712 struct f_midi *midi = substream->rmidi->private_data; in f_midi_in_open()
713 struct gmidi_in_port *port; in f_midi_in_open() local
715 if (substream->number >= midi->in_ports) in f_midi_in_open()
716 return -EINVAL; in f_midi_in_open()
719 port = midi->in_ports_array + substream->number; in f_midi_in_open()
720 port->substream = substream; in f_midi_in_open()
721 port->state = STATE_INITIAL; in f_midi_in_open()
727 struct f_midi *midi = substream->rmidi->private_data; in f_midi_in_close()
735 struct f_midi *midi = substream->rmidi->private_data; in f_midi_in_trigger()
737 if (substream->number >= midi->in_ports) in f_midi_in_trigger()
741 midi->in_ports_array[substream->number].active = up; in f_midi_in_trigger()
743 queue_work(system_highpri_wq, &midi->work); in f_midi_in_trigger()
748 struct f_midi *midi = substream->rmidi->private_data; in f_midi_out_open()
750 if (substream->number >= MAX_PORTS) in f_midi_out_open()
751 return -EINVAL; in f_midi_out_open()
754 midi->out_substream[substream->number] = substream; in f_midi_out_open()
760 struct f_midi *midi = substream->rmidi->private_data; in f_midi_out_close()
768 struct f_midi *midi = substream->rmidi->private_data; in f_midi_out_trigger()
773 set_bit(substream->number, &midi->out_triggered); in f_midi_out_trigger()
775 clear_bit(substream->number, &midi->out_triggered); in f_midi_out_trigger()
792 if (midi->card) { in f_midi_unregister_card()
793 snd_card_free(midi->card); in f_midi_unregister_card()
794 midi->card = NULL; in f_midi_unregister_card()
808 err = snd_card_new(&midi->gadget->dev, midi->index, midi->id, in f_midi_register_card()
814 midi->card = card; in f_midi_register_card()
822 strscpy(card->driver, f_midi_longname); in f_midi_register_card()
823 strscpy(card->longname, f_midi_longname); in f_midi_register_card()
824 strscpy(card->shortname, f_midi_shortname); in f_midi_register_card()
828 err = snd_rawmidi_new(card, card->longname, 0, in f_midi_register_card()
829 midi->out_ports, midi->in_ports, &rmidi); in f_midi_register_card()
834 midi->rmidi = rmidi; in f_midi_register_card()
835 midi->in_last_port = 0; in f_midi_register_card()
836 strscpy(rmidi->name, card->shortname); in f_midi_register_card()
837 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | in f_midi_register_card()
840 rmidi->private_data = midi; in f_midi_register_card()
841 rmidi->private_free = f_midi_rmidi_free; in f_midi_register_card()
842 midi->free_ref++; in f_midi_register_card()
845 * Yes, rawmidi OUTPUT = USB IN, and rawmidi INPUT = USB OUT. in f_midi_register_card()
846 * It's an upside-down world being a gadget. in f_midi_register_card()
851 /* register it - we're ready to go */ in f_midi_register_card()
875 struct usb_composite_dev *cdev = c->cdev; in f_midi_bind()
880 midi->gadget = cdev->gadget; in f_midi_bind()
881 INIT_WORK(&midi->work, f_midi_in_work); in f_midi_bind()
886 /* maybe allocate device-global string ID */ in f_midi_bind()
887 us = usb_gstrings_attach(c->cdev, midi_strings, in f_midi_bind()
893 ac_interface_desc.iInterface = us[STRING_FUNC_IDX].id; in f_midi_bind()
906 midi->ms_id = status; in f_midi_bind()
908 status = -ENODEV; in f_midi_bind()
919 /* allocate instance-specific endpoints */ in f_midi_bind()
920 midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc); in f_midi_bind()
921 if (!midi->in_ep) in f_midi_bind()
924 midi->out_ep = usb_ep_autoconfig(cdev->gadget, &bulk_out_desc); in f_midi_bind()
925 if (!midi->out_ep) in f_midi_bind()
932 status = -ENOMEM; in f_midi_bind()
942 /* add the headers - these are always the same */ in f_midi_bind()
949 + (midi->in_ports + midi->out_ports) * in f_midi_bind()
956 for (n = 0; n < midi->in_ports; n++) { in f_midi_bind()
960 in_ext->bLength = USB_DT_MIDI_IN_SIZE; in f_midi_bind()
961 in_ext->bDescriptorType = USB_DT_CS_INTERFACE; in f_midi_bind()
962 in_ext->bDescriptorSubtype = USB_MS_MIDI_IN_JACK; in f_midi_bind()
963 in_ext->bJackType = USB_MS_EXTERNAL; in f_midi_bind()
964 in_ext->bJackID = jack++; in f_midi_bind()
965 in_ext->iJack = 0; in f_midi_bind()
968 out_emb->bLength = USB_DT_MIDI_OUT_SIZE(1); in f_midi_bind()
969 out_emb->bDescriptorType = USB_DT_CS_INTERFACE; in f_midi_bind()
970 out_emb->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK; in f_midi_bind()
971 out_emb->bJackType = USB_MS_EMBEDDED; in f_midi_bind()
972 out_emb->bJackID = jack++; in f_midi_bind()
973 out_emb->bNrInputPins = 1; in f_midi_bind()
974 out_emb->pins[0].baSourcePin = 1; in f_midi_bind()
975 out_emb->pins[0].baSourceID = in_ext->bJackID; in f_midi_bind()
976 out_emb->iJack = 0; in f_midi_bind()
980 ms_in_desc.baAssocJackID[n] = out_emb->bJackID; in f_midi_bind()
984 for (n = 0; n < midi->out_ports; n++) { in f_midi_bind()
988 in_emb->bLength = USB_DT_MIDI_IN_SIZE; in f_midi_bind()
989 in_emb->bDescriptorType = USB_DT_CS_INTERFACE; in f_midi_bind()
990 in_emb->bDescriptorSubtype = USB_MS_MIDI_IN_JACK; in f_midi_bind()
991 in_emb->bJackType = USB_MS_EMBEDDED; in f_midi_bind()
992 in_emb->bJackID = jack++; in f_midi_bind()
993 in_emb->iJack = 0; in f_midi_bind()
996 out_ext->bLength = USB_DT_MIDI_OUT_SIZE(1); in f_midi_bind()
997 out_ext->bDescriptorType = USB_DT_CS_INTERFACE; in f_midi_bind()
998 out_ext->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK; in f_midi_bind()
999 out_ext->bJackType = USB_MS_EXTERNAL; in f_midi_bind()
1000 out_ext->bJackID = jack++; in f_midi_bind()
1001 out_ext->bNrInputPins = 1; in f_midi_bind()
1002 out_ext->iJack = 0; in f_midi_bind()
1003 out_ext->pins[0].baSourceID = in_emb->bJackID; in f_midi_bind()
1004 out_ext->pins[0].baSourcePin = 1; in f_midi_bind()
1008 ms_out_desc.baAssocJackID[n] = in_emb->bJackID; in f_midi_bind()
1012 ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); in f_midi_bind()
1013 ms_out_desc.bNumEmbMIDIJack = midi->out_ports; in f_midi_bind()
1015 ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); in f_midi_bind()
1016 ms_in_desc.bNumEmbMIDIJack = midi->in_ports; in f_midi_bind()
1028 * hardware is dual speed, all bulk-capable endpoints work at in f_midi_bind()
1032 f->fs_descriptors = usb_copy_descriptors(midi_function); in f_midi_bind()
1033 if (!f->fs_descriptors) in f_midi_bind()
1038 f->hs_descriptors = usb_copy_descriptors(midi_function); in f_midi_bind()
1039 if (!f->hs_descriptors) in f_midi_bind()
1057 f->ss_descriptors = usb_copy_descriptors(midi_function); in f_midi_bind()
1058 if (!f->ss_descriptors) in f_midi_bind()
1071 ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); in f_midi_bind()
1086 usb_put_function_instance(&opts->func_inst); in midi_attr_release()
1099 mutex_lock(&opts->lock); \
1100 result = sprintf(page, "%u\n", opts->name); \
1101 mutex_unlock(&opts->lock); \
1113 mutex_lock(&opts->lock); \
1114 if (opts->refcnt > 1) { \
1115 ret = -EBUSY; \
1124 ret = -EINVAL; \
1127 opts->name = num; \
1131 mutex_unlock(&opts->lock); \
1143 mutex_lock(&opts->lock); \
1144 result = sprintf(page, "%d\n", opts->name); \
1145 mutex_unlock(&opts->lock); \
1157 mutex_lock(&opts->lock); \
1158 if (opts->refcnt > 1) { \
1159 ret = -EBUSY; \
1168 ret = -EINVAL; \
1171 opts->name = num; \
1175 mutex_unlock(&opts->lock); \
1192 mutex_lock(&opts->lock); in f_midi_opts_id_show()
1193 if (opts->id) { in f_midi_opts_id_show()
1194 result = strscpy(page, opts->id, PAGE_SIZE); in f_midi_opts_id_show()
1200 mutex_unlock(&opts->lock); in f_midi_opts_id_show()
1212 mutex_lock(&opts->lock); in f_midi_opts_id_store()
1213 if (opts->refcnt > 1) { in f_midi_opts_id_store()
1214 ret = -EBUSY; in f_midi_opts_id_store()
1220 ret = -ENOMEM; in f_midi_opts_id_store()
1223 if (opts->id_allocated) in f_midi_opts_id_store()
1224 kfree(opts->id); in f_midi_opts_id_store()
1225 opts->id = c; in f_midi_opts_id_store()
1226 opts->id_allocated = true; in f_midi_opts_id_store()
1229 mutex_unlock(&opts->lock); in f_midi_opts_id_store()
1233 CONFIGFS_ATTR(f_midi_opts_, id);
1258 mutex_lock(&opts->lock); in f_midi_free_inst()
1259 if (!--opts->refcnt) { in f_midi_free_inst()
1262 mutex_unlock(&opts->lock); in f_midi_free_inst()
1265 if (opts->id_allocated) in f_midi_free_inst()
1266 kfree(opts->id); in f_midi_free_inst()
1277 return ERR_PTR(-ENOMEM); in f_midi_alloc_inst()
1279 mutex_init(&opts->lock); in f_midi_alloc_inst()
1280 opts->func_inst.free_func_inst = f_midi_free_inst; in f_midi_alloc_inst()
1281 opts->index = SNDRV_DEFAULT_IDX1; in f_midi_alloc_inst()
1282 opts->id = SNDRV_DEFAULT_STR1; in f_midi_alloc_inst()
1283 opts->buflen = 512; in f_midi_alloc_inst()
1284 opts->qlen = 32; in f_midi_alloc_inst()
1285 opts->in_ports = 1; in f_midi_alloc_inst()
1286 opts->out_ports = 1; in f_midi_alloc_inst()
1287 opts->refcnt = 1; in f_midi_alloc_inst()
1289 config_group_init_type_name(&opts->func_inst.group, "", in f_midi_alloc_inst()
1292 return &opts->func_inst; in f_midi_alloc_inst()
1302 opts = container_of(f->fi, struct f_midi_opts, func_inst); in f_midi_free()
1303 mutex_lock(&opts->lock); in f_midi_free()
1304 if (!--midi->free_ref) { in f_midi_free()
1305 kfree(midi->id); in f_midi_free()
1306 kfifo_free(&midi->in_req_fifo); in f_midi_free()
1310 mutex_unlock(&opts->lock); in f_midi_free()
1313 f_midi_free_inst(&opts->func_inst); in f_midi_free()
1318 f_midi_free(rmidi->private_data); in f_midi_rmidi_free()
1323 struct usb_composite_dev *cdev = f->config->cdev; in f_midi_unbind()
1332 card = midi->card; in f_midi_unbind()
1333 midi->card = NULL; in f_midi_unbind()
1348 mutex_lock(&opts->lock); in f_midi_alloc()
1350 if (opts->in_ports > MAX_PORTS || opts->out_ports > MAX_PORTS) { in f_midi_alloc()
1351 status = -EINVAL; in f_midi_alloc()
1356 midi = kzalloc(struct_size(midi, in_ports_array, opts->in_ports), in f_midi_alloc()
1359 status = -ENOMEM; in f_midi_alloc()
1362 midi->in_ports = opts->in_ports; in f_midi_alloc()
1364 for (i = 0; i < opts->in_ports; i++) in f_midi_alloc()
1365 midi->in_ports_array[i].cable = i; in f_midi_alloc()
1368 midi->id = kstrdup(opts->id, GFP_KERNEL); in f_midi_alloc()
1369 if (opts->id && !midi->id) { in f_midi_alloc()
1370 status = -ENOMEM; in f_midi_alloc()
1373 midi->out_ports = opts->out_ports; in f_midi_alloc()
1374 midi->index = opts->index; in f_midi_alloc()
1375 midi->buflen = opts->buflen; in f_midi_alloc()
1376 midi->qlen = opts->qlen; in f_midi_alloc()
1377 midi->in_last_port = 0; in f_midi_alloc()
1378 midi->free_ref = 1; in f_midi_alloc()
1380 status = kfifo_alloc(&midi->in_req_fifo, midi->qlen, GFP_KERNEL); in f_midi_alloc()
1384 spin_lock_init(&midi->transmit_lock); in f_midi_alloc()
1386 ++opts->refcnt; in f_midi_alloc()
1387 mutex_unlock(&opts->lock); in f_midi_alloc()
1389 midi->func.name = "gmidi function"; in f_midi_alloc()
1390 midi->func.bind = f_midi_bind; in f_midi_alloc()
1391 midi->func.unbind = f_midi_unbind; in f_midi_alloc()
1392 midi->func.set_alt = f_midi_set_alt; in f_midi_alloc()
1393 midi->func.disable = f_midi_disable; in f_midi_alloc()
1394 midi->func.free_func = f_midi_free; in f_midi_alloc()
1396 return &midi->func; in f_midi_alloc()
1400 kfree(midi->id); in f_midi_alloc()
1403 mutex_unlock(&opts->lock); in f_midi_alloc()