> -----Original Message----- > From: John Youn [mailto:John.Youn@xxxxxxxxxxxx] > Sent: Wednesday, June 10, 2015 1:06 AM > To: Kaukab, Yousaf; linux-usb@xxxxxxxxxxxxxxx; balbi@xxxxxx; > john.youn@xxxxxxxxxxxx > Cc: Herrero, Gregory; heiko@xxxxxxxxx; Holmberg, Hans > Subject: Re: [PATCH 1/3] usb: dwc2: host: allocate qh before atomic enqueue > > On 6/5/2015 7:23 AM, Mian Yousaf Kaukab wrote: > > To avoid sleep while atomic bugs, allocate qh before calling > > dwc2_hcd_urb_enqueue. qh pointer can be used directly now instead of > > passing ep->hcpriv as double pointer. > > > > Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@xxxxxxxxx> > > --- > > drivers/usb/dwc2/hcd.c | 31 ++++++++++++++++++++++++++---- > > drivers/usb/dwc2/hcd.h | 5 ++++- > > drivers/usb/dwc2/hcd_queue.c | 45 > > ++++++++++++-------------------------------- > > 3 files changed, 43 insertions(+), 38 deletions(-) > > > > diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index > > b10377c..80bce71 100644 > > --- a/drivers/usb/dwc2/hcd.c > > +++ b/drivers/usb/dwc2/hcd.c > > @@ -359,7 +359,7 @@ void dwc2_hcd_stop(struct dwc2_hsotg *hsotg) > > > > /* Caller must hold driver lock */ > > static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, > > - struct > dwc2_hcd_urb *urb, void **ep_handle, > > + struct > dwc2_hcd_urb *urb, struct dwc2_qh *qh, > > gfp_t mem_flags) > > { > > struct dwc2_qtd *qtd; > > @@ -391,8 +391,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg > *hsotg, > > return -ENOMEM; > > > > dwc2_hcd_qtd_init(qtd, urb); > > - retval = dwc2_hcd_qtd_add(hsotg, qtd, (struct dwc2_qh > **)ep_handle, > > - mem_flags); > > + retval = dwc2_hcd_qtd_add(hsotg, qtd, qh); > > if (retval) { > > dev_err(hsotg->dev, > > "DWC OTG HCD URB Enqueue > failed adding QTD. Error status %d\n", @@ > > -2445,6 +2444,8 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, > struct urb *urb, > > u32 tflags = 0; > > void *buf; > > unsigned long flags; > > + struct dwc2_qh *qh; > > + bool qh_allocated = false; > > > > if (dbg_urb(urb)) { > > dev_vdbg(hsotg->dev, "DWC OTG HCD URB > Enqueue\n"); @@ -2523,13 > > +2524,24 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct > urb *urb, > > > urb->iso_frame_desc[i].length); > > > > urb->hcpriv = dwc2_urb; > > + qh = (struct dwc2_qh *) ep->hcpriv; > > + /* Create QH for the endpoint if it doesn't exist */ > > + if (!qh) { > > + qh = dwc2_hcd_qh_create(hsotg, dwc2_urb, > mem_flags); > > + if (!qh) { > > + retval = -ENOMEM; > > + goto fail0; > > + } > > + ep->hcpriv = qh; > > + qh_allocated = true; > > + } > > > > spin_lock_irqsave(&hsotg->lock, flags); > > retval = usb_hcd_link_urb_to_ep(hcd, urb); > > if (retval) > > goto fail1; > > > > - retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, &ep->hcpriv, > mem_flags); > > + retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, qh, > mem_flags); > > if (retval) > > goto fail2; > > > > @@ -2549,6 +2561,17 @@ fail2: > > fail1: > > spin_unlock_irqrestore(&hsotg->lock, flags); > > urb->hcpriv = NULL; > > + if (qh_allocated) { > > + struct dwc2_qtd *qtd2, *qtd2_tmp; > > + > > + ep->hcpriv = NULL; > > + dwc2_hcd_qh_unlink(hsotg, qh); > > + /* Free each QTD in the QH's QTD list */ > > + list_for_each_entry_safe(qtd2, qtd2_tmp, &qh- > >qtd_list, > > + > qtd_list_entry) > > + > dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh); > > + dwc2_hcd_qh_free(hsotg, qh); > > + } > > fail0: > > kfree(dwc2_urb); > > > > diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index > > 7b5841c..fc10549 100644 > > --- a/drivers/usb/dwc2/hcd.h > > +++ b/drivers/usb/dwc2/hcd.h > > @@ -463,6 +463,9 @@ extern void dwc2_hcd_queue_transactions(struct > > dwc2_hsotg *hsotg, > > /* Schedule Queue Functions */ > > /* Implemented in hcd_queue.c */ > > extern void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg); > > +extern struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, > > + > struct dwc2_hcd_urb *urb, > > + > gfp_t mem_flags); > > extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh > > *qh); extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct > > dwc2_qh *qh); extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg > > *hsotg, struct dwc2_qh *qh); @@ -471,7 +474,7 @@ extern void > > dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, > > > > extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct > > dwc2_hcd_urb *urb); extern int dwc2_hcd_qtd_add(struct dwc2_hsotg > *hsotg, struct dwc2_qtd *qtd, > > - struct dwc2_qh **qh, gfp_t > mem_flags); > > + struct dwc2_qh *qh); > > > > /* Unlinks and frees a QTD */ > > static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg > > *hsotg, diff --git a/drivers/usb/dwc2/hcd_queue.c > > b/drivers/usb/dwc2/hcd_queue.c index 9b5c362..e573a4f 100644 > > --- a/drivers/usb/dwc2/hcd_queue.c > > +++ b/drivers/usb/dwc2/hcd_queue.c > > @@ -191,7 +191,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, > struct dwc2_qh *qh, > > * > > * Return: Pointer to the newly allocated QH, or NULL on error > > */ > > -static struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, > > +struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, > > > struct dwc2_hcd_urb *urb, > > > gfp_t mem_flags) > > { > > @@ -767,57 +767,36 @@ void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, > struct dwc2_hcd_urb *urb) > > * > > * @hsotg: The DWC HCD structure > > * @qtd: The QTD to add > > - * @qh: Out parameter to return queue head > > - * @atomic_alloc: Flag to do atomic alloc if needed > > + * @qh: Queue head to add qtd to > > * > > * Return: 0 if successful, negative error code otherwise > > * > > - * Finds the correct QH to place the QTD into. If it does not find a > > QH, it > > - * will create a new QH. If the QH to which the QTD is added is not > > currently > > - * scheduled, it is placed into the proper schedule based on its EP type. > > + * If the QH to which the QTD is added is not currently scheduled, it > > + is placed > > + * into the proper schedule based on its EP type. > > */ > > int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, > > - struct dwc2_qh **qh, gfp_t mem_flags) > > + struct dwc2_qh *qh) > > { > > - struct dwc2_hcd_urb *urb = qtd->urb; > > - int allocated = 0; > > int retval; > > > > /* > > * Get the QH which holds the QTD-list to insert to. Create QH if > it > > * doesn't exist. > > */ > > This comment doesn't apply anymore. Otherwise the series looks ok. Applies cleanly to testing/next at my end. I just noticed that the patch is truncated on gmane (http://permalink.gmane.org/gmane.linux.usb.general/126493). Looks OK on other sites. I will resend the whole series anyway. > > Acked-by: John Youn <johnyoun@xxxxxxxxxxxx> > > > John > /Yousaf -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html