summaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea/udc.c
diff options
context:
space:
mode:
authorFelipe F. Tonello2015-10-27 11:36:32 +0100
committerPeter Chen2015-12-24 07:15:26 +0100
commit779debdf26d4b49598e61e0c28ac97146a2b96fe (patch)
treef7f8690838478842e3d19203c136ff498cd58883 /drivers/usb/chipidea/udc.c
parentusb: chipidea: udc: _ep_queue and _hw_queue cleanup (diff)
downloadkernel-qcow2-linux-779debdf26d4b49598e61e0c28ac97146a2b96fe.tar.gz
kernel-qcow2-linux-779debdf26d4b49598e61e0c28ac97146a2b96fe.tar.xz
kernel-qcow2-linux-779debdf26d4b49598e61e0c28ac97146a2b96fe.zip
usb: chipidea: udc: improve error handling on _hardware_enqueue
_hardware_enqueue() didn't check for errors when using add_td_to_list() which can fail if dma_pool_alloc fails, thus causing a kernel panic when lastnode->ptr is NULL. Signed-off-by: Felipe F. Tonello <eu@felipetonello.com> Signed-off-by: Peter Chen <peter.chen@freescale.com>
Diffstat (limited to 'drivers/usb/chipidea/udc.c')
-rw-r--r--drivers/usb/chipidea/udc.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index d917b3f27ddb..b1e7b716e8c9 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -434,19 +434,28 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
if (hwreq->req.dma % PAGE_SIZE)
pages--;
- if (rest == 0)
- add_td_to_list(hwep, hwreq, 0);
+ if (rest == 0) {
+ ret = add_td_to_list(hwep, hwreq, 0);
+ if (ret < 0)
+ goto done;
+ }
while (rest > 0) {
unsigned count = min(hwreq->req.length - hwreq->req.actual,
(unsigned)(pages * CI_HDRC_PAGE_SIZE));
- add_td_to_list(hwep, hwreq, count);
+ ret = add_td_to_list(hwep, hwreq, count);
+ if (ret < 0)
+ goto done;
+
rest -= count;
}
if (hwreq->req.zero && hwreq->req.length && hwep->dir == TX
- && (hwreq->req.length % hwep->ep.maxpacket == 0))
- add_td_to_list(hwep, hwreq, 0);
+ && (hwreq->req.length % hwep->ep.maxpacket == 0)) {
+ ret = add_td_to_list(hwep, hwreq, 0);
+ if (ret < 0)
+ goto done;
+ }
firstnode = list_first_entry(&hwreq->tds, struct td_node, td);