@@ -148,7 +148,6 @@ struct snd_usb_midi_out_endpoint {
struct snd_usb_midi_out_endpoint* ep;
struct snd_rawmidi_substream *substream;
int active;
- bool autopm_reference;
uint8_t cable; /* cable number << 4 */
uint8_t state;
#define STATE_UNKNOWN 0
@@ -1033,29 +1032,35 @@ static void update_roland_altsetting(struct snd_usb_midi* umidi)
snd_usbmidi_input_start(&umidi->list);
}
-static void substream_open(struct snd_rawmidi_substream *substream, int open)
+static int substream_open(struct snd_rawmidi_substream *substream, int open)
{
struct snd_usb_midi* umidi = substream->rmidi->private_data;
struct snd_kcontrol *ctl;
+ int err = 0;
mutex_lock(&umidi->mutex);
- if (open) {
- if (umidi->opened++ == 0 && umidi->roland_load_ctl) {
+ if (open && umidi->opened++ == 0) {
+ err = usb_autopm_get_interface(umidi->iface);
+ if (err == -EACCES)
+ err = 0;
+ if (!err && umidi->roland_load_ctl) {
ctl = umidi->roland_load_ctl;
ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(umidi->card,
SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
update_roland_altsetting(umidi);
}
- } else {
- if (--umidi->opened == 0 && umidi->roland_load_ctl) {
+ } else if (!open && --umidi->opened == 0) {
+ if (umidi->roland_load_ctl) {
ctl = umidi->roland_load_ctl;
ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(umidi->card,
SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
}
+ usb_autopm_put_interface(umidi->iface);
}
mutex_unlock(&umidi->mutex);
+ return err;
}
static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
@@ -1076,25 +1081,17 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
snd_BUG();
return -ENXIO;
}
- err = usb_autopm_get_interface(umidi->iface);
- port->autopm_reference = err >= 0;
- if (err < 0 && err != -EACCES)
- return -EIO;
+ err = substream_open(substream, 1);
+ if (err < 0)
+ return err;
substream->runtime->private_data = port;
port->state = STATE_UNKNOWN;
- substream_open(substream, 1);
return 0;
}
static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
{
- struct snd_usb_midi* umidi = substream->rmidi->private_data;
- struct usbmidi_out_port *port = substream->runtime->private_data;
-
- substream_open(substream, 0);
- if (port->autopm_reference)
- usb_autopm_put_interface(umidi->iface);
- return 0;
+ return substream_open(substream, 0);
}
static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -1147,14 +1144,12 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream)
{
- substream_open(substream, 1);
- return 0;
+ return substream_open(substream, 1);
}
static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream)
{
- substream_open(substream, 0);
- return 0;
+ return substream_open(substream, 0);
}
static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)