Re: usb: dwc3: query: dma sg implementation for isoc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Sep 11, 2012 at 12:29:36PM +0530, Pratyush Anand wrote:
> On 9/10/2012 6:49 PM, Felipe Balbi wrote:
> >On Mon, Sep 10, 2012 at 06:45:06PM +0530, Pratyush Anand wrote:
> >>Hi Felip,
> >>
> >>Thanks for the clarifications.
> >>
> >>On 9/10/2012 6:29 PM, Felipe Balbi wrote:
> >>>>If my understanding is correct, then I might need to modify dwc3
> >>>>>driver a bit. only first TRB of the service interval should have
> >>>>>TRBCTL as ISOC_FIRST rest should have TRBCTL as ISOC.
> >>>Why ? IIRC, ISOC_FIRST was a hint to the internal packet scheduler to
> >>>give higher priority to the isochronous packet, right ? Does it make any
> >>>difference for your use case ?
> >>
> >>Databook says:
> >>
> >>
> >>"The first TRB in a Buffer Descriptor must have the TRBCTL field set
> >>to the “Isochronous-First” type while all others have this field set
> >>to “Isochronous”."
> >
> >aaa true :-) I had forgotten about that extra bit of information when
> >using chained TRBs :-s My bad. Please send a patch.
> >
> >>So I thought to modify the code. As of now, ISOC IN does not work
> >>fully with either All Isochronous-First or Isochronous First +
> >>Isochronous implementation (in case of more than one TRB for one
> >>service interval).
> >>May be I am doing some mistake in my code. :(
> >>I am debugging. Will get back with my observations.
> >
> >I think you're perfectly right at the need for ISOCHRONOUS_FIRST flag.
> >My bad.
> >
> 
> Hummm.. It works with "Isochronous First + Isochronous"
> implementation. But, code needs many modification..
> 
> We have one trb and one trb_dma per "struct dwc3_request". We take
> lot of decisions on the basis of req->trb value. These all will
> change in case of SG. We will not have only one TRB per "struct
> usb_request".
> 
> I am going to keep array for trb and trb_dma and then to manage all
> these with backward compatibility (non SG case). What do you say?
> 
> struct dwc3_trb         *trb[DWC3_TRB_NUM];
> dma_addr_t              trb_dma[DWC3_TRB_NUM];

that doesn't look right :-(

Isn't something like below enough ?

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 3ddf779..330556b 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -749,7 +749,8 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
  */
 static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
 		struct dwc3_request *req, dma_addr_t dma,
-		unsigned length, unsigned last, unsigned chain)
+		unsigned length, unsigned first, unsigned last,
+		unsigned chain)
 {
 	struct dwc3		*dwc = dep->dwc;
 	struct dwc3_trb		*trb;
@@ -786,7 +787,10 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
 		break;
 
 	case USB_ENDPOINT_XFER_ISOC:
-		trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
+		if (first && chain)
+			trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
+		else
+			trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
 
 		if (!req->request.no_interrupt)
 			trb->ctrl |= DWC3_TRB_CTRL_IOC;
@@ -912,7 +916,8 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
 					chain = false;
 
 				dwc3_prepare_one_trb(dep, req, dma, length,
-						last_one, chain);
+						(i == 0), first_one, last_one,
+						chain);
 
 				if (last_one)
 					break;

-- 
balbi

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux