From: Peter Chen Date: Wed, 19 Feb 2014 05:41:41 +0000 (+0800) Subject: usb: chipidea: udc: refine ep operation at isr_tr_complete_handler X-Git-Tag: next-20140306~23^2~17 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=64fc06c40e01;p=karo-tx-linux.git usb: chipidea: udc: refine ep operation at isr_tr_complete_handler - delete the warning message at interrupt handler, and adds judgement at ep_enable, if non-ep0 requests ctrl transfer, it will indicate an error. - delete hw_test_and_clear_setup_status which is a broken code - Tested with g_mass_storage, g_ncm, g_ether Cc: matthieu.castet@parrot.com Reported-by: Michael Grzeschik Acked-by: Michael Grzeschik Tested-by: Michael Grzeschik Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 0a61c6688bc1..0dc56aebb807 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -177,19 +177,6 @@ static int hw_ep_get_halt(struct ci_hdrc *ci, int num, int dir) return hw_read(ci, OP_ENDPTCTRL + num, mask) ? 1 : 0; } -/** - * hw_test_and_clear_setup_status: test & clear setup status (execute without - * interruption) - * @n: endpoint number - * - * This function returns setup status - */ -static int hw_test_and_clear_setup_status(struct ci_hdrc *ci, int n) -{ - n = ep_to_bit(ci, n); - return hw_test_and_clear(ci, OP_ENDPTSETUPSTAT, BIT(n)); -} - /** * hw_ep_prime: primes endpoint (execute without interruption) * @num: endpoint number @@ -997,14 +984,10 @@ __acquires(ci->lock) } } - if (hwep->type != USB_ENDPOINT_XFER_CONTROL || - !hw_test_and_clear_setup_status(ci, i)) - continue; - - if (i != 0) { - dev_warn(ci->dev, "ctrl traffic at endpoint %d\n", i); + /* Only handle setup packet below */ + if (i != 0 || + !hw_test_and_clear(ci, OP_ENDPTSETUPSTAT, BIT(0))) continue; - } /* * Flush data and handshake transactions of previous @@ -1193,6 +1176,11 @@ static int ep_enable(struct usb_ep *ep, hwep->qh.ptr->td.next |= cpu_to_le32(TD_TERMINATE); /* needed? */ + if (hwep->num != 0 && hwep->type == USB_ENDPOINT_XFER_CONTROL) { + dev_err(hwep->ci->dev, "Set control xfer at non-ep0\n"); + retval = -EINVAL; + } + /* * Enable endpoints in the HW other than ep0 as ep0 * is always enabled