sound: usb: Return error if any member API fails

Currently, the driver undoes the previously done work on an
API failure, but it still returns 0(SUCCESS) as
internal_status in the QMI response. Hence AFE still queues
data leading to null pointer dereference.
Fix this by returning error on failure of any member routine.

Change-Id: Ia056044dd26191d25a7b5d5591f9c622eff9ca3c
Signed-off-by: Ajay Agarwal <ajaya@codeaurora.org>
This commit is contained in:
Ajay Agarwal 2018-09-05 14:16:28 +05:30 committed by Gerrit - the friendly Code Review server
parent d8f81fe4d6
commit 65193871b9

View File

@ -447,7 +447,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
struct uac_format_type_i_discrete_descriptor *fmt_v1;
struct uac_format_type_i_ext_descriptor *fmt_v2;
struct uac1_as_header_descriptor *as;
int ret = -ENODEV;
int ret;
int protocol, card_num, pcm_dev_num;
void *hdr_ptr;
u8 *xfer_buf;
@ -462,6 +462,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
if (!iface) {
pr_err("%s: interface # %d does not exist\n", __func__,
subs->interface);
ret = -ENODEV;
goto err;
}
@ -480,12 +481,14 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
if (!fmt) {
pr_err("%s: %u:%d : no UAC_FORMAT_TYPE desc\n",
__func__, subs->interface, subs->altset_idx);
ret = -ENODEV;
goto err;
}
}
if (!uadev[card_num].ctrl_intf) {
pr_err("%s: audio ctrl intf info not cached\n", __func__);
ret = -ENODEV;
goto err;
}
@ -496,6 +499,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
NULL, UAC_HEADER);
if (!hdr_ptr) {
pr_err("%s: no UAC_HEADER desc\n", __func__);
ret = -ENODEV;
goto err;
}
}
@ -506,6 +510,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
if (!as) {
pr_err("%s: %u:%d : no UAC_AS_GENERAL desc\n", __func__,
subs->interface, subs->altset_idx);
ret = -ENODEV;
goto err;
}
resp->data_path_delay = as->bDelay;
@ -552,6 +557,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
resp->usb_audio_subslot_size_valid = 1;
} else {
pr_err("%s: unknown protocol version %x\n", __func__, protocol);
ret = -ENODEV;
goto err;
}
@ -565,6 +571,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
if (!ep) {
pr_err("%s: data ep # %d context is null\n", __func__,
subs->data_endpoint->ep_num);
ret = -ENODEV;
goto err;
}
data_ep_pipe = subs->data_endpoint->pipe;
@ -574,6 +581,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
tr_data_pa = usb_get_xfer_ring_phys_addr(subs->dev, ep, &dma);
if (!tr_data_pa) {
pr_err("%s:failed to get data ep ring dma address\n", __func__);
ret = -ENODEV;
goto err;
}
@ -593,6 +601,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
if (!tr_sync_pa) {
pr_err("%s:failed to get sync ep ring dma address\n",
__func__);
ret = -ENODEV;
goto err;
}
resp->xhci_mem_info.tr_sync.pa = dma;
@ -618,17 +627,21 @@ skip_sync_ep:
ret);
goto err;
}
xhci_pa = usb_get_sec_event_ring_phys_addr(subs->dev,
resp->interrupter_num, &dma);
if (!xhci_pa) {
pr_err("%s: failed to get sec event ring dma address\n",
__func__);
ret = -ENODEV;
goto err;
}
va = uaudio_iommu_map(MEM_EVENT_RING, xhci_pa, PAGE_SIZE, NULL);
if (!va)
if (!va) {
ret = -ENOMEM;
goto err;
}
resp->xhci_mem_info.evt_ring.va = PREPEND_SID_TO_IOVA(va,
uaudio_qdev->sid);
@ -637,15 +650,19 @@ skip_sync_ep:
uaudio_qdev->er_mapped = true;
resp->speed_info = get_speed_info(subs->dev->speed);
if (resp->speed_info == USB_AUDIO_DEVICE_SPEED_INVALID_V01)
if (resp->speed_info == USB_AUDIO_DEVICE_SPEED_INVALID_V01) {
ret = -ENODEV;
goto unmap_er;
}
resp->speed_info_valid = 1;
/* data transfer ring */
va = uaudio_iommu_map(MEM_XFER_RING, tr_data_pa, PAGE_SIZE, NULL);
if (!va)
if (!va) {
ret = -ENOMEM;
goto unmap_er;
}
tr_data_va = va;
resp->xhci_mem_info.tr_data.va = PREPEND_SID_TO_IOVA(va,
@ -658,8 +675,10 @@ skip_sync_ep:
xhci_pa = resp->xhci_mem_info.tr_sync.pa;
va = uaudio_iommu_map(MEM_XFER_RING, tr_sync_pa, PAGE_SIZE, NULL);
if (!va)
if (!va) {
ret = -ENOMEM;
goto unmap_data;
}
tr_sync_va = va;
resp->xhci_mem_info.tr_sync.va = PREPEND_SID_TO_IOVA(va,
@ -683,14 +702,18 @@ skip_sync:
}
xfer_buf = usb_alloc_coherent(subs->dev, len, GFP_KERNEL, &xfer_buf_pa);
if (!xfer_buf)
if (!xfer_buf) {
ret = -ENOMEM;
goto unmap_sync;
}
dma_get_sgtable(subs->dev->bus->sysdev, &sgt, xfer_buf, xfer_buf_pa,
len);
va = uaudio_iommu_map(MEM_XFER_BUF, xfer_buf_pa, len, &sgt);
if (!va)
if (!va) {
ret = -ENOMEM;
goto unmap_sync;
}
resp->xhci_mem_info.xfer_buff.pa = xfer_buf_pa;
resp->xhci_mem_info.xfer_buff.size = len;