summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-09-15 22:51:48 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-09-15 22:51:48 -0700
commit27332002f81356d2b71e2be91879bde8586d51ec (patch)
treee10c9cad50d2111435904400e4a61b285b70019a
parentd2afad6a903bdda2f803fae49f0b0001d12f8600 (diff)
parentb73866cdb1c9dbdce1371646abe449956dfe2ca0 (diff)
Merge "sound: usb: Send explicit device disconnect to clients"
-rw-r--r--sound/usb/card.c5
-rw-r--r--sound/usb/usb_audio_qmi_svc.c42
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(&register_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(&register_mutex);
- if (chip->disconnect_cb)
- chip->disconnect_cb(chip);
snd_card_free_when_closed(card);
} else {
mutex_unlock(&register_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 */