0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/slab.h>
0009 #include <linux/usb.h>
0010 #include <linux/export.h>
0011 #include <sound/core.h>
0012 #include <sound/rawmidi.h>
0013
0014 #include "driver.h"
0015 #include "midi.h"
0016
0017 #define line6_rawmidi_substream_midi(substream) \
0018 ((struct snd_line6_midi *)((substream)->rmidi->private_data))
0019
0020 static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
0021 int length);
0022
0023
0024
0025
0026 void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
0027 int length)
0028 {
0029 if (line6->line6midi->substream_receive)
0030 snd_rawmidi_receive(line6->line6midi->substream_receive,
0031 data, length);
0032 }
0033
0034
0035
0036
0037 static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
0038 {
0039 struct usb_line6 *line6 =
0040 line6_rawmidi_substream_midi(substream)->line6;
0041 struct snd_line6_midi *line6midi = line6->line6midi;
0042 struct midi_buffer *mb = &line6midi->midibuf_out;
0043 unsigned char chunk[LINE6_FALLBACK_MAXPACKETSIZE];
0044 int req, done;
0045
0046 for (;;) {
0047 req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
0048 done = snd_rawmidi_transmit_peek(substream, chunk, req);
0049
0050 if (done == 0)
0051 break;
0052
0053 line6_midibuf_write(mb, chunk, done);
0054 snd_rawmidi_transmit_ack(substream, done);
0055 }
0056
0057 for (;;) {
0058 done = line6_midibuf_read(mb, chunk,
0059 LINE6_FALLBACK_MAXPACKETSIZE);
0060
0061 if (done == 0)
0062 break;
0063
0064 send_midi_async(line6, chunk, done);
0065 }
0066 }
0067
0068
0069
0070
0071 static void midi_sent(struct urb *urb)
0072 {
0073 unsigned long flags;
0074 int status;
0075 int num;
0076 struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
0077
0078 status = urb->status;
0079 kfree(urb->transfer_buffer);
0080 usb_free_urb(urb);
0081
0082 if (status == -ESHUTDOWN)
0083 return;
0084
0085 spin_lock_irqsave(&line6->line6midi->lock, flags);
0086 num = --line6->line6midi->num_active_send_urbs;
0087
0088 if (num == 0) {
0089 line6_midi_transmit(line6->line6midi->substream_transmit);
0090 num = line6->line6midi->num_active_send_urbs;
0091 }
0092
0093 if (num == 0)
0094 wake_up(&line6->line6midi->send_wait);
0095
0096 spin_unlock_irqrestore(&line6->line6midi->lock, flags);
0097 }
0098
0099
0100
0101
0102
0103
0104 static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
0105 int length)
0106 {
0107 struct urb *urb;
0108 int retval;
0109 unsigned char *transfer_buffer;
0110
0111 urb = usb_alloc_urb(0, GFP_ATOMIC);
0112
0113 if (urb == NULL)
0114 return -ENOMEM;
0115
0116 transfer_buffer = kmemdup(data, length, GFP_ATOMIC);
0117
0118 if (transfer_buffer == NULL) {
0119 usb_free_urb(urb);
0120 return -ENOMEM;
0121 }
0122
0123 usb_fill_int_urb(urb, line6->usbdev,
0124 usb_sndintpipe(line6->usbdev,
0125 line6->properties->ep_ctrl_w),
0126 transfer_buffer, length, midi_sent, line6,
0127 line6->interval);
0128 urb->actual_length = 0;
0129 retval = usb_urb_ep_type_check(urb);
0130 if (retval < 0)
0131 goto error;
0132
0133 retval = usb_submit_urb(urb, GFP_ATOMIC);
0134 if (retval < 0)
0135 goto error;
0136
0137 ++line6->line6midi->num_active_send_urbs;
0138 return 0;
0139
0140 error:
0141 dev_err(line6->ifcdev, "usb_submit_urb failed\n");
0142 usb_free_urb(urb);
0143 return retval;
0144 }
0145
0146 static int line6_midi_output_open(struct snd_rawmidi_substream *substream)
0147 {
0148 return 0;
0149 }
0150
0151 static int line6_midi_output_close(struct snd_rawmidi_substream *substream)
0152 {
0153 return 0;
0154 }
0155
0156 static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
0157 int up)
0158 {
0159 unsigned long flags;
0160 struct usb_line6 *line6 =
0161 line6_rawmidi_substream_midi(substream)->line6;
0162
0163 line6->line6midi->substream_transmit = substream;
0164 spin_lock_irqsave(&line6->line6midi->lock, flags);
0165
0166 if (line6->line6midi->num_active_send_urbs == 0)
0167 line6_midi_transmit(substream);
0168
0169 spin_unlock_irqrestore(&line6->line6midi->lock, flags);
0170 }
0171
0172 static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
0173 {
0174 struct usb_line6 *line6 =
0175 line6_rawmidi_substream_midi(substream)->line6;
0176 struct snd_line6_midi *midi = line6->line6midi;
0177
0178 wait_event_interruptible(midi->send_wait,
0179 midi->num_active_send_urbs == 0);
0180 }
0181
0182 static int line6_midi_input_open(struct snd_rawmidi_substream *substream)
0183 {
0184 return 0;
0185 }
0186
0187 static int line6_midi_input_close(struct snd_rawmidi_substream *substream)
0188 {
0189 return 0;
0190 }
0191
0192 static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,
0193 int up)
0194 {
0195 struct usb_line6 *line6 =
0196 line6_rawmidi_substream_midi(substream)->line6;
0197
0198 if (up)
0199 line6->line6midi->substream_receive = substream;
0200 else
0201 line6->line6midi->substream_receive = NULL;
0202 }
0203
0204 static const struct snd_rawmidi_ops line6_midi_output_ops = {
0205 .open = line6_midi_output_open,
0206 .close = line6_midi_output_close,
0207 .trigger = line6_midi_output_trigger,
0208 .drain = line6_midi_output_drain,
0209 };
0210
0211 static const struct snd_rawmidi_ops line6_midi_input_ops = {
0212 .open = line6_midi_input_open,
0213 .close = line6_midi_input_close,
0214 .trigger = line6_midi_input_trigger,
0215 };
0216
0217
0218 static int snd_line6_new_midi(struct usb_line6 *line6,
0219 struct snd_rawmidi **rmidi_ret)
0220 {
0221 struct snd_rawmidi *rmidi;
0222 int err;
0223
0224 err = snd_rawmidi_new(line6->card, "Line 6 MIDI", 0, 1, 1, rmidi_ret);
0225 if (err < 0)
0226 return err;
0227
0228 rmidi = *rmidi_ret;
0229 strcpy(rmidi->id, line6->properties->id);
0230 strcpy(rmidi->name, line6->properties->name);
0231
0232 rmidi->info_flags =
0233 SNDRV_RAWMIDI_INFO_OUTPUT |
0234 SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
0235
0236 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
0237 &line6_midi_output_ops);
0238 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
0239 &line6_midi_input_ops);
0240 return 0;
0241 }
0242
0243
0244 static void snd_line6_midi_free(struct snd_rawmidi *rmidi)
0245 {
0246 struct snd_line6_midi *line6midi = rmidi->private_data;
0247
0248 line6_midibuf_destroy(&line6midi->midibuf_in);
0249 line6_midibuf_destroy(&line6midi->midibuf_out);
0250 kfree(line6midi);
0251 }
0252
0253
0254
0255
0256 int line6_init_midi(struct usb_line6 *line6)
0257 {
0258 int err;
0259 struct snd_rawmidi *rmidi;
0260 struct snd_line6_midi *line6midi;
0261
0262 if (!(line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI)) {
0263
0264 return 0;
0265 }
0266
0267 err = snd_line6_new_midi(line6, &rmidi);
0268 if (err < 0)
0269 return err;
0270
0271 line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
0272 if (!line6midi)
0273 return -ENOMEM;
0274
0275 rmidi->private_data = line6midi;
0276 rmidi->private_free = snd_line6_midi_free;
0277
0278 init_waitqueue_head(&line6midi->send_wait);
0279 spin_lock_init(&line6midi->lock);
0280 line6midi->line6 = line6;
0281
0282 err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
0283 if (err < 0)
0284 return err;
0285
0286 err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
0287 if (err < 0)
0288 return err;
0289
0290 line6->line6midi = line6midi;
0291 return 0;
0292 }
0293 EXPORT_SYMBOL_GPL(line6_init_midi);