diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2016-09-15 22:51:48 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-09-15 22:51:48 -0700 |
commit | 27332002f81356d2b71e2be91879bde8586d51ec (patch) | |
tree | e10c9cad50d2111435904400e4a61b285b70019a | |
parent | d2afad6a903bdda2f803fae49f0b0001d12f8600 (diff) | |
parent | b73866cdb1c9dbdce1371646abe449956dfe2ca0 (diff) |
Merge "sound: usb: Send explicit device disconnect to clients"
-rw-r--r-- | sound/usb/card.c | 5 | ||||
-rw-r--r-- | sound/usb/usb_audio_qmi_svc.c | 42 |
2 files changed, 36 insertions, 11 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c index 524688e4c144..1f6c247f773a 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -673,6 +673,9 @@ static void usb_audio_disconnect(struct usb_interface *intf) card = chip->card; + if (chip->disconnect_cb) + chip->disconnect_cb(chip); + mutex_lock(®ister_mutex); if (atomic_inc_return(&chip->shutdown) == 1) { struct snd_usb_stream *as; @@ -707,8 +710,6 @@ static void usb_audio_disconnect(struct usb_interface *intf) if (chip->num_interfaces <= 0) { usb_chip[chip->index] = NULL; mutex_unlock(®ister_mutex); - if (chip->disconnect_cb) - chip->disconnect_cb(chip); snd_card_free_when_closed(card); } else { mutex_unlock(®ister_mutex); diff --git a/sound/usb/usb_audio_qmi_svc.c b/sound/usb/usb_audio_qmi_svc.c index fa0206cc14c6..8337d11bad12 100644 --- a/sound/usb/usb_audio_qmi_svc.c +++ b/sound/usb/usb_audio_qmi_svc.c @@ -134,6 +134,12 @@ static struct msg_desc uaudio_stream_resp_desc = { .ei_array = qmi_uaudio_stream_resp_msg_v01_ei, }; +static struct msg_desc uaudio_stream_ind_desc = { + .max_msg_len = QMI_UAUDIO_STREAM_IND_MSG_V01_MAX_MSG_LEN, + .msg_id = QMI_UADUIO_STREAM_IND_V01, + .ei_array = qmi_uaudio_stream_ind_msg_v01_ei, +}; + enum mem_type { MEM_EVENT_RING, MEM_DCBA, @@ -643,29 +649,47 @@ void uaudio_disconnect_cb(struct snd_usb_audio *chip) int ret, if_idx; struct uaudio_dev *dev; int card_num = chip->card_num; + struct uaudio_qmi_svc *svc = uaudio_svc; + struct qmi_uaudio_stream_ind_msg_v01 disconnect_ind = {0}; pr_debug("%s: for card# %d\n", __func__, card_num); - mutex_lock(&chip->dev_lock); if (card_num >= SNDRV_CARDS) { pr_err("%s: invalid card number\n", __func__); - goto done; + return; } + mutex_lock(&chip->dev_lock); dev = &uadev[card_num]; + + /* clean up */ + if (!dev->udev) { + pr_debug("%s: no clean up required\n", __func__); + goto done; + } + if (atomic_read(&dev->in_use)) { + mutex_unlock(&chip->dev_lock); + + pr_debug("%s: sending qmi indication disconnect\n", __func__); + disconnect_ind.dev_event = USB_AUDIO_DEV_DISCONNECT_V01; + disconnect_ind.slot_id = dev->udev->slot_id; + ret = qmi_send_ind(svc->uaudio_svc_hdl, svc->curr_conn, + &uaudio_stream_ind_desc, &disconnect_ind, + sizeof(disconnect_ind)); + if (ret < 0) { + pr_err("%s: qmi send failed wiht err: %d\n", + __func__, ret); + return; + } + ret = wait_event_interruptible(dev->disconnect_wq, !atomic_read(&dev->in_use)); if (ret < 0) { pr_debug("%s: failed with ret %d\n", __func__, ret); - goto done; + return; } - } - - /* clean up */ - if (!dev->udev) { - pr_debug("%s: no clean up required\n", __func__); - goto done; + mutex_lock(&chip->dev_lock); } /* free xfer buffer and unmap xfer ring and buf per interface */ |