| .. | .. |
|---|
| 91 | 91 | __u8 bDescriptorType; |
|---|
| 92 | 92 | __u8 bDescriptorSubtype; |
|---|
| 93 | 93 | __u8 bNumEmbMIDIJack; |
|---|
| 94 | | - __u8 baAssocJackID[0]; |
|---|
| 94 | + __u8 baAssocJackID[]; |
|---|
| 95 | 95 | } __attribute__ ((packed)); |
|---|
| 96 | 96 | |
|---|
| 97 | 97 | struct snd_usb_midi_in_endpoint; |
|---|
| .. | .. |
|---|
| 142 | 142 | unsigned int active_urbs; |
|---|
| 143 | 143 | unsigned int drain_urbs; |
|---|
| 144 | 144 | int max_transfer; /* size of urb buffer */ |
|---|
| 145 | | - struct tasklet_struct tasklet; |
|---|
| 145 | + struct work_struct work; |
|---|
| 146 | 146 | unsigned int next_urb; |
|---|
| 147 | 147 | spinlock_t buffer_lock; |
|---|
| 148 | 148 | |
|---|
| .. | .. |
|---|
| 344 | 344 | spin_unlock_irqrestore(&ep->buffer_lock, flags); |
|---|
| 345 | 345 | } |
|---|
| 346 | 346 | |
|---|
| 347 | | -static void snd_usbmidi_out_tasklet(unsigned long data) |
|---|
| 347 | +static void snd_usbmidi_out_work(struct work_struct *work) |
|---|
| 348 | 348 | { |
|---|
| 349 | 349 | struct snd_usb_midi_out_endpoint *ep = |
|---|
| 350 | | - (struct snd_usb_midi_out_endpoint *) data; |
|---|
| 350 | + container_of(work, struct snd_usb_midi_out_endpoint, work); |
|---|
| 351 | 351 | |
|---|
| 352 | 352 | snd_usbmidi_do_output(ep); |
|---|
| 353 | 353 | } |
|---|
| .. | .. |
|---|
| 1149 | 1149 | port = &umidi->endpoints[i].out->ports[j]; |
|---|
| 1150 | 1150 | break; |
|---|
| 1151 | 1151 | } |
|---|
| 1152 | | - if (!port) { |
|---|
| 1153 | | - snd_BUG(); |
|---|
| 1152 | + if (!port) |
|---|
| 1154 | 1153 | return -ENXIO; |
|---|
| 1155 | | - } |
|---|
| 1156 | 1154 | |
|---|
| 1157 | 1155 | substream->runtime->private_data = port; |
|---|
| 1158 | 1156 | port->state = STATE_UNKNOWN; |
|---|
| .. | .. |
|---|
| 1161 | 1159 | |
|---|
| 1162 | 1160 | static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) |
|---|
| 1163 | 1161 | { |
|---|
| 1162 | + struct usbmidi_out_port *port = substream->runtime->private_data; |
|---|
| 1163 | + |
|---|
| 1164 | + cancel_work_sync(&port->ep->work); |
|---|
| 1164 | 1165 | return substream_open(substream, 0, 0); |
|---|
| 1165 | 1166 | } |
|---|
| 1166 | 1167 | |
|---|
| .. | .. |
|---|
| 1175 | 1176 | if (port->ep->umidi->disconnected) { |
|---|
| 1176 | 1177 | /* gobble up remaining bytes to prevent wait in |
|---|
| 1177 | 1178 | * snd_rawmidi_drain_output */ |
|---|
| 1178 | | - while (!snd_rawmidi_transmit_empty(substream)) |
|---|
| 1179 | | - snd_rawmidi_transmit_ack(substream, 1); |
|---|
| 1179 | + snd_rawmidi_proceed(substream); |
|---|
| 1180 | 1180 | return; |
|---|
| 1181 | 1181 | } |
|---|
| 1182 | | - tasklet_schedule(&port->ep->tasklet); |
|---|
| 1182 | + queue_work(system_highpri_wq, &port->ep->work); |
|---|
| 1183 | 1183 | } |
|---|
| 1184 | 1184 | } |
|---|
| 1185 | 1185 | |
|---|
| .. | .. |
|---|
| 1211 | 1211 | } while (drain_urbs && timeout); |
|---|
| 1212 | 1212 | finish_wait(&ep->drain_wait, &wait); |
|---|
| 1213 | 1213 | } |
|---|
| 1214 | + port->active = 0; |
|---|
| 1214 | 1215 | spin_unlock_irq(&ep->buffer_lock); |
|---|
| 1215 | 1216 | } |
|---|
| 1216 | 1217 | |
|---|
| .. | .. |
|---|
| 1409 | 1410 | /* |
|---|
| 1410 | 1411 | * Some devices only work with 9 bytes packet size: |
|---|
| 1411 | 1412 | */ |
|---|
| 1412 | | - case USB_ID(0x0644, 0x800E): /* Tascam US-122L */ |
|---|
| 1413 | | - case USB_ID(0x0644, 0x800F): /* Tascam US-144 */ |
|---|
| 1413 | + case USB_ID(0x0644, 0x800e): /* Tascam US-122L */ |
|---|
| 1414 | + case USB_ID(0x0644, 0x800f): /* Tascam US-144 */ |
|---|
| 1414 | 1415 | ep->max_transfer = 9; |
|---|
| 1415 | 1416 | break; |
|---|
| 1416 | 1417 | } |
|---|
| .. | .. |
|---|
| 1442 | 1443 | } |
|---|
| 1443 | 1444 | |
|---|
| 1444 | 1445 | spin_lock_init(&ep->buffer_lock); |
|---|
| 1445 | | - tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep); |
|---|
| 1446 | + INIT_WORK(&ep->work, snd_usbmidi_out_work); |
|---|
| 1446 | 1447 | init_waitqueue_head(&ep->drain_wait); |
|---|
| 1447 | 1448 | |
|---|
| 1448 | 1449 | for (i = 0; i < 0x10; ++i) |
|---|
| .. | .. |
|---|
| 1505 | 1506 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { |
|---|
| 1506 | 1507 | struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i]; |
|---|
| 1507 | 1508 | if (ep->out) |
|---|
| 1508 | | - tasklet_kill(&ep->out->tasklet); |
|---|
| 1509 | + cancel_work_sync(&ep->out->work); |
|---|
| 1509 | 1510 | if (ep->out) { |
|---|
| 1510 | 1511 | for (j = 0; j < OUTPUT_URBS; ++j) |
|---|
| 1511 | 1512 | usb_kill_urb(ep->out->urbs[j].urb); |
|---|
| .. | .. |
|---|
| 2417 | 2418 | break; |
|---|
| 2418 | 2419 | case QUIRK_MIDI_US122L: |
|---|
| 2419 | 2420 | umidi->usb_protocol_ops = &snd_usbmidi_122l_ops; |
|---|
| 2420 | | - /* fall through */ |
|---|
| 2421 | + fallthrough; |
|---|
| 2421 | 2422 | case QUIRK_MIDI_FIXED_ENDPOINT: |
|---|
| 2422 | 2423 | memcpy(&endpoints[0], quirk->data, |
|---|
| 2423 | 2424 | sizeof(struct snd_usb_midi_endpoint_info)); |
|---|