Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-07-07 Thread sundeep subbaraya
Hi Felipe,

On Wed, Jul 2, 2014 at 10:16 PM, Felipe Balbi ba...@ti.com wrote:
 Hi,

 On Sun, May 25, 2014 at 11:10:30PM +0530, sundeep subbaraya wrote:
 Hi Felipe,

 Please take a look at below about how this IP works:

 IN:
   req.buf --- DMA (transfers from ddr to IP buffer, raise DMA
 done interrupt and set Buffer ready to transfer data to Host)Host
 PC
   buffer sent interrupt

 OUT:
  Host PC---buffer ready interrupt---DMA (transfer from IP buffer
 to DDR,DMA done interrupt, set Buffer ready to receive next data from
 Host)--req.buf

 I written logic to call completion in DMA done handler because it
 works for both IN and OUT eps. But I see significant performance
 degradation (by copying a file to mass storage gadget). DMA can handle
 unaligned address too but it has ep max limit (say 512 for bulk).
 Hence it is SW job to split packets and to drive DMA till req.length
 completes. I feel polling for a while is faster than switching between
 interrupt handler back and forth rapidly. Moreover, DMA may or may not
 be present in IP based on user configuration at design time.

 I fixed all other comments expect this one if you do not agree for
 polling then I may have to create threads and do this stuff. What do
 you suggest?

 Can you resend your driver so we can review again everything you have
 fixed ? I guess you have no other way... polling it is.

Sure. I will resend the driver.

Thanks,
Sundeep.B.S.


 cheers

 --
 balbi
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-07-02 Thread Felipe Balbi
Hi,

On Sun, May 25, 2014 at 11:10:30PM +0530, sundeep subbaraya wrote:
 Hi Felipe,
 
 Please take a look at below about how this IP works:
 
 IN:
   req.buf --- DMA (transfers from ddr to IP buffer, raise DMA
 done interrupt and set Buffer ready to transfer data to Host)Host
 PC
   buffer sent interrupt
 
 OUT:
  Host PC---buffer ready interrupt---DMA (transfer from IP buffer
 to DDR,DMA done interrupt, set Buffer ready to receive next data from
 Host)--req.buf
 
 I written logic to call completion in DMA done handler because it
 works for both IN and OUT eps. But I see significant performance
 degradation (by copying a file to mass storage gadget). DMA can handle
 unaligned address too but it has ep max limit (say 512 for bulk).
 Hence it is SW job to split packets and to drive DMA till req.length
 completes. I feel polling for a while is faster than switching between
 interrupt handler back and forth rapidly. Moreover, DMA may or may not
 be present in IP based on user configuration at design time.
 
 I fixed all other comments expect this one if you do not agree for
 polling then I may have to create threads and do this stuff. What do
 you suggest?

Can you resend your driver so we can review again everything you have
fixed ? I guess you have no other way... polling it is.

cheers

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-05-25 Thread sundeep subbaraya
Hi Felipe,

Please take a look at below about how this IP works:

IN:
  req.buf --- DMA (transfers from ddr to IP buffer, raise DMA
done interrupt and set Buffer ready to transfer data to Host)Host
PC
  buffer sent interrupt

OUT:
 Host PC---buffer ready interrupt---DMA (transfer from IP buffer
to DDR,DMA done interrupt, set Buffer ready to receive next data from
Host)--req.buf

I written logic to call completion in DMA done handler because it
works for both IN and OUT eps. But I see significant performance
degradation (by copying a file to mass storage gadget). DMA can handle
unaligned address too but it has ep max limit (say 512 for bulk).
Hence it is SW job to split packets and to drive DMA till req.length
completes. I feel polling for a while is faster than switching between
interrupt handler back and forth rapidly. Moreover, DMA may or may not
be present in IP based on user configuration at design time.

I fixed all other comments expect this one if you do not agree for
polling then I may have to create threads and do this stuff. What do
you suggest?

Thanks,
Sundeep

On Wed, Apr 30, 2014 at 10:24 PM, Felipe Balbi ba...@ti.com wrote:
 Hi,

 On Wed, Apr 23, 2014 at 09:57:52AM +0530, sundeep subbaraya wrote:
   I get the impression that the two of you are arguing past each other.
   It appears that Sundeep is talking about transferring data from the
   gadget driver's buffer to an internal buffer in the UDC hardware, but
   Felipe is talking about transferring data from the UDC to the host.
  
   As I understand it, Sundeep said that when the gadget driver queues a
   data-IN request, the UDC driver copies as much of the data buffer as
   possible into a hardware FIFO.  If it succeeds in copying all the data
   into the FIFO then the request's completion routine gets called
   immediately, even though the data doesn't get sent from the FIFO to the
   host until the host asks for it.
  
   If only part of the data can be copied into the FIFO then the request
   is added to the ep's request queue before the usb_ep_queue() call
   returns.  When space becomes available in the FIFO, the data will be
   copied and eventually sent to the host.  When all the data has been
   copied to the FIFO, the request's completion routine will be called.
 
  there seems to be a slight problem with this approach: how will the IP
  know that even though you copied X bytes into the FIFO, it should wait
  for another Y bytes before shifting data to the wire ? How will it know
  that it shouldn't generate CRC yet because there's still data to be
  added ?

 No. IP does/need not know that it has to wait for Y bytes.We just
 write X bytes into
 HW buffer and count as X in buffer count register. IP generates CRC
 for bytes based
 on Count register and sends data to Host. Let us consider this
 scenario of bulk IN transfer:
 req.length = 5120 and   wMaxPacketSize = 512, ep_queue is called once
 and is returned with
 status 0. In ep_queue this code snippet,
if (xudc_write_fifo(ep, req) == 1)
 req = NULL;
if(req != NULL)
  list_add_tail(req-queue, ep-queue);

 xudc_write_fifo does the following if HW buffers not busy:
  copies 512 bytes to HW buffer
  set count and ready registers so that IP can start data transfer to host
  changes req.actual to 512 and returns 0(if req.length 
 wMaxPacketSize) and 1(if req.length  wMaxPacketSize).

 you should return a proper error code, not 1.

 Since return is zero this request is added to queue. When data
 transfer to host is completed IP generates
 an interrupt. In the interrupt handler we again call write_fifo if
 request list is not empty.
if (list_empty(ep-queue))
 req = NULL;
 else
 req = list_entry(ep-queue.next, struct xusb_req, queue);
 if (!req)
 return;

 okay, this can be improved a bit though:

 if (list_empty(ep-queue))
 return;

 req = list_first_entry(ep-queue, struct xusb_req, queue);

 if (ep-is_in)
 xudc_write_fifo(ep, req);
 else
 xudc_read_fifo(ep, req);

 This happens 10 times(since length 5120) and completion is called.

 ok.

  If there's no space in the FIFO yet, why copy data at all ?

 If HW buffers are busy(IP is still transferring previous data to Host
 from buffer) then xudc_write_fifo returns 0 without changing
 req.actual. When previous data transfer completes then Interrupt then
 again write_fifo from handler.

 ok, sounds good to me.

   Thus there never is any need for the gadget driver to queue the request
   again.

 Yes

  An incomplete transfer means the FIFO didn't have enough room
   when the request was submitted; it doesn't mean that the data didn't
   eventually get sent to the host.
 
  Exactly Alan,this is what I was trying to say. Probably I was not
  clear in explaining. I didnt see any harm this 

Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-22 Thread sundeep subbaraya
Hi,

On Mon, Apr 21, 2014 at 10:09 PM, Alan Stern st...@rowland.harvard.edu wrote:
 On Mon, 21 Apr 2014, Felipe Balbi wrote:

 Hi,

 On Fri, Apr 18, 2014 at 07:34:08PM +0530, sundeep subbaraya wrote:

 snip

   in ep_queue driver starts dma transfer from/to IP buffer to/from 
   req-buf.
   If transfer is completed then request is not added to ep request queue
   and returns from ep_queue.
   If transfer is not completed (actual  length) then request is added
   to queue and returns from ep_queue.
  
   This is wrong. Why wouldn't you give gadget driver the chance to decide
   if it needs to queue the request again or not ?
 
  When does gadget driver decides to queue the same request again?
  if -EBUSY is returned from ep_queue or req.status != 0 in completion
  routine?

 whenever it so decides. Different gadget drivers might have different
 requirements. The code is open and sits under drivers/usb/gadget/ why
 don't you have a read ?

 I get the impression that the two of you are arguing past each other.
 It appears that Sundeep is talking about transferring data from the
 gadget driver's buffer to an internal buffer in the UDC hardware, but
 Felipe is talking about transferring data from the UDC to the host.

 As I understand it, Sundeep said that when the gadget driver queues a
 data-IN request, the UDC driver copies as much of the data buffer as
 possible into a hardware FIFO.  If it succeeds in copying all the data
 into the FIFO then the request's completion routine gets called
 immediately, even though the data doesn't get sent from the FIFO to the
 host until the host asks for it.

 If only part of the data can be copied into the FIFO then the request
 is added to the ep's request queue before the usb_ep_queue() call
 returns.  When space becomes available in the FIFO, the data will be
 copied and eventually sent to the host.  When all the data has been
 copied to the FIFO, the request's completion routine will be called.

 Thus there never is any need for the gadget driver to queue the request
 again.  An incomplete transfer means the FIFO didn't have enough room
 when the request was submitted; it doesn't mean that the data didn't
 eventually get sent to the host.

Exactly Alan,this is what I was trying to say. Probably I was not
clear in explaining. I didnt see
any harm this way and even this implementation is same like
at91_udc.c. I have been reading
mas_storage to understand when does gadget driver tries to enqueue a
request again. Since
different gadget drivers might have different requirements (agree with
Felipe), wanted to
know criteria for queuing a same request again.

I will change this implementation as per Felipe comments and test with
some of the gadgets.

Thanks Alan and Felipe,
Sundeep


 HTH,

 Alan Stern

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-22 Thread Alan Stern
On Tue, 22 Apr 2014, sundeep subbaraya wrote:

 Hi,
 
 On Mon, Apr 21, 2014 at 10:09 PM, Alan Stern st...@rowland.harvard.edu 
 wrote:
  On Mon, 21 Apr 2014, Felipe Balbi wrote:
 
  Hi,
 
  On Fri, Apr 18, 2014 at 07:34:08PM +0530, sundeep subbaraya wrote:
 
  snip
 
in ep_queue driver starts dma transfer from/to IP buffer to/from 
req-buf.
If transfer is completed then request is not added to ep request queue
and returns from ep_queue.
If transfer is not completed (actual  length) then request is added
to queue and returns from ep_queue.
   
This is wrong. Why wouldn't you give gadget driver the chance to decide
if it needs to queue the request again or not ?
  
   When does gadget driver decides to queue the same request again?
   if -EBUSY is returned from ep_queue or req.status != 0 in completion
   routine?
 
  whenever it so decides. Different gadget drivers might have different
  requirements. The code is open and sits under drivers/usb/gadget/ why
  don't you have a read ?
 
  I get the impression that the two of you are arguing past each other.
  It appears that Sundeep is talking about transferring data from the
  gadget driver's buffer to an internal buffer in the UDC hardware, but
  Felipe is talking about transferring data from the UDC to the host.
 
  As I understand it, Sundeep said that when the gadget driver queues a
  data-IN request, the UDC driver copies as much of the data buffer as
  possible into a hardware FIFO.  If it succeeds in copying all the data
  into the FIFO then the request's completion routine gets called
  immediately, even though the data doesn't get sent from the FIFO to the
  host until the host asks for it.
 
  If only part of the data can be copied into the FIFO then the request
  is added to the ep's request queue before the usb_ep_queue() call
  returns.  When space becomes available in the FIFO, the data will be
  copied and eventually sent to the host.  When all the data has been
  copied to the FIFO, the request's completion routine will be called.
 
  Thus there never is any need for the gadget driver to queue the request
  again.  An incomplete transfer means the FIFO didn't have enough room
  when the request was submitted; it doesn't mean that the data didn't
  eventually get sent to the host.
 
 Exactly Alan,this is what I was trying to say. Probably I was not
 clear in explaining. I didnt see
 any harm this way and even this implementation is same like
 at91_udc.c. I have been reading
 mas_storage to understand when does gadget driver tries to enqueue a
 request again. Since
 different gadget drivers might have different requirements (agree with
 Felipe), wanted to
 know criteria for queuing a same request again.
 
 I will change this implementation as per Felipe comments and test with
 some of the gadgets.

Wait until you hear what Felipe has to say about this discussion.  
Maybe he will decide that the original implementation was correct.

Alan Stern

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-22 Thread Felipe Balbi
Hi,

On Tue, Apr 22, 2014 at 12:58:41PM +0530, sundeep subbaraya wrote:
 Hi,
 
 On Mon, Apr 21, 2014 at 10:09 PM, Alan Stern st...@rowland.harvard.edu 
 wrote:
  On Mon, 21 Apr 2014, Felipe Balbi wrote:
 
  Hi,
 
  On Fri, Apr 18, 2014 at 07:34:08PM +0530, sundeep subbaraya wrote:
 
  snip
 
in ep_queue driver starts dma transfer from/to IP buffer to/from 
req-buf.
If transfer is completed then request is not added to ep request queue
and returns from ep_queue.
If transfer is not completed (actual  length) then request is added
to queue and returns from ep_queue.
   
This is wrong. Why wouldn't you give gadget driver the chance to decide
if it needs to queue the request again or not ?
  
   When does gadget driver decides to queue the same request again?
   if -EBUSY is returned from ep_queue or req.status != 0 in completion
   routine?
 
  whenever it so decides. Different gadget drivers might have different
  requirements. The code is open and sits under drivers/usb/gadget/ why
  don't you have a read ?
 
  I get the impression that the two of you are arguing past each other.
  It appears that Sundeep is talking about transferring data from the
  gadget driver's buffer to an internal buffer in the UDC hardware, but
  Felipe is talking about transferring data from the UDC to the host.
 
  As I understand it, Sundeep said that when the gadget driver queues a
  data-IN request, the UDC driver copies as much of the data buffer as
  possible into a hardware FIFO.  If it succeeds in copying all the data
  into the FIFO then the request's completion routine gets called
  immediately, even though the data doesn't get sent from the FIFO to the
  host until the host asks for it.
 
  If only part of the data can be copied into the FIFO then the request
  is added to the ep's request queue before the usb_ep_queue() call
  returns.  When space becomes available in the FIFO, the data will be
  copied and eventually sent to the host.  When all the data has been
  copied to the FIFO, the request's completion routine will be called.

there seems to be a slight problem with this approach: how will the IP
know that even though you copied X bytes into the FIFO, it should wait
for another Y bytes before shifting data to the wire ? How will it know
that it shouldn't generate CRC yet because there's still data to be
added ?

If there's no space in the FIFO yet, why copy data at all ?

  Thus there never is any need for the gadget driver to queue the request
  again.  An incomplete transfer means the FIFO didn't have enough room
  when the request was submitted; it doesn't mean that the data didn't
  eventually get sent to the host.
 
 Exactly Alan,this is what I was trying to say. Probably I was not
 clear in explaining. I didnt see any harm this way and even this
 implementation is same like at91_udc.c. I have been reading
 mas_storage to understand when does gadget driver tries to enqueue a
 request again. Since different gadget drivers might have different
 requirements (agree with Felipe), wanted to know criteria for queuing
 a same request again.
 
 I will change this implementation as per Felipe comments and test with
 some of the gadgets.

Let's see, please help me understand the questions above.

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-21 Thread Felipe Balbi
Hi,

On Fri, Apr 18, 2014 at 07:34:08PM +0530, sundeep subbaraya wrote:

snip

  in ep_queue driver starts dma transfer from/to IP buffer to/from req-buf.
  If transfer is completed then request is not added to ep request queue
  and returns from ep_queue.
  If transfer is not completed (actual  length) then request is added
  to queue and returns from ep_queue.
 
  This is wrong. Why wouldn't you give gadget driver the chance to decide
  if it needs to queue the request again or not ?
 
 When does gadget driver decides to queue the same request again?
 if -EBUSY is returned from ep_queue or req.status != 0 in completion
 routine?

whenever it so decides. Different gadget drivers might have different
requirements. The code is open and sits under drivers/usb/gadget/ why
don't you have a read ?

 there are cases where ping-pong buffers both are busy. currently this driver
 adds request to queue only when buffers are busy. In normal cases request is
 processed without adding to queue.

it shouldn't do that. You can't add requests by yourself. If you can't
initiate transfers right now, let the HW NAK or something.

 do i need to have another local queue for requests waiting since
 buffers are busy?

you should probably move the request to another queue, yes. Here's what
dwc3 does:

. gadget queues request
. dwc3 puts request in a 'queued' list
. HW sends XferNotReady event to notify it needs transfer requests
. dwc3 moves requests to 'pending' list
. dwc3 tells hw to consume 'pending' list

if gadget driver queues another request, we accept it into 'queued' list
and wait for another XferNotReady before moving it to 'pending' and
consuming it.

 Or dequeue the request ?

you could return -EAGAIN, if you wish. But don't add requests by
yourself, this could end up in hard-to-debug scenarios. Remember you
don't *own* the reqeusts, only gadget drivers do. You can keep the
request around until you have space in your FIFOs to start it, but then,
in that case, don't try to list_del() - start() - list_add().

  when buffer processed interrupt occurs, handler starts dma if there is
  request in queue and calls complete call back (when actual == length)
  Hence answer is Yes for some transfers (start dma called from
  interrupt handler not from ep_queue).
 
  this also seems wrong(-ish).
 
  1) as Paul pointed out, you can't rely on jiffies if you're calling this
  with IRQs disabled.
 
  2) you don't really need to wait until DMA finishes its transaction
  before returning from start_dma(), just use the DMA completion IRQ,
 
  3) I don't see anywhere any sanitizing of arguments, can your DMA really
  handle any alignment/unaligned addresses or should you make sure you're
  getting good arguments?
 
  You need to work on this a little bit, I guess.
 
 Yes am working on this and will be using seperate ep_ops for ep0  like
 drivers/usb/dwc3/gadget.c since ep0 has no dma and ping-pong buffers

ok

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-21 Thread Alan Stern
On Mon, 21 Apr 2014, Felipe Balbi wrote:

 Hi,
 
 On Fri, Apr 18, 2014 at 07:34:08PM +0530, sundeep subbaraya wrote:
 
 snip
 
   in ep_queue driver starts dma transfer from/to IP buffer to/from 
   req-buf.
   If transfer is completed then request is not added to ep request queue
   and returns from ep_queue.
   If transfer is not completed (actual  length) then request is added
   to queue and returns from ep_queue.
  
   This is wrong. Why wouldn't you give gadget driver the chance to decide
   if it needs to queue the request again or not ?
  
  When does gadget driver decides to queue the same request again?
  if -EBUSY is returned from ep_queue or req.status != 0 in completion
  routine?
 
 whenever it so decides. Different gadget drivers might have different
 requirements. The code is open and sits under drivers/usb/gadget/ why
 don't you have a read ?

I get the impression that the two of you are arguing past each other.
It appears that Sundeep is talking about transferring data from the 
gadget driver's buffer to an internal buffer in the UDC hardware, but 
Felipe is talking about transferring data from the UDC to the host.

As I understand it, Sundeep said that when the gadget driver queues a
data-IN request, the UDC driver copies as much of the data buffer as
possible into a hardware FIFO.  If it succeeds in copying all the data
into the FIFO then the request's completion routine gets called
immediately, even though the data doesn't get sent from the FIFO to the
host until the host asks for it.

If only part of the data can be copied into the FIFO then the request
is added to the ep's request queue before the usb_ep_queue() call
returns.  When space becomes available in the FIFO, the data will be
copied and eventually sent to the host.  When all the data has been
copied to the FIFO, the request's completion routine will be called.

Thus there never is any need for the gadget driver to queue the request
again.  An incomplete transfer means the FIFO didn't have enough room
when the request was submitted; it doesn't mean that the data didn't
eventually get sent to the host.

HTH,

Alan Stern

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-18 Thread sundeep subbaraya
Hi Felipe,

On Thu, Apr 17, 2014 at 8:31 PM, Felipe Balbi ba...@ti.com wrote:
 On Thu, Apr 17, 2014 at 03:01:37PM +0530, sundeep subbaraya wrote:
 Hi Felipe,

 On Wed, Apr 16, 2014 at 11:32 PM, Felipe Balbi ba...@ti.com wrote:
  Hi,
 
  On Wed, Apr 16, 2014 at 04:09:28PM +0530, sundeep subbaraya wrote:
  Hi Felipe,
 
  On Thu, Apr 3, 2014 at 8:28 PM, Felipe Balbi ba...@ti.com wrote:
 
   +static int start_dma(struct xusb_ep *ep, u32 src, u32 dst, u32 length)
  
   please prepend this with xudc_, it makes tracing a lot easier.
  
   +{
   + struct xusb_udc *udc;
   + int rc = 0;
   + unsigned long timeout;
   +
   + udc = ep-udc;
   + /*
   +  * Set the addresses in the DMA source and
   +  * destination registers and then set the length
   +  * into the DMA length register.
   +  */
   + udc-write_fn(udc-base_address, XUSB_DMA_DSAR_ADDR_OFFSET, src);
   + udc-write_fn(udc-base_address, XUSB_DMA_DDAR_ADDR_OFFSET, dst);
   + udc-write_fn(udc-base_address, XUSB_DMA_LENGTH_OFFSET, length);
   +
   + /*
   +  * Wait till DMA transaction is complete and
   +  * check whether the DMA transaction was
   +  * successful.
   + */
   + while ((udc-read_fn(ep-udc-base_address + 
   XUSB_DMA_STATUS_OFFSET) 
   + XUSB_DMA_DMASR_BUSY) == XUSB_DMA_DMASR_BUSY) {
   + timeout = jiffies + 1;
   +
   + if (time_after(jiffies, timeout)) {
   + rc = -ETIMEDOUT;
   + goto clean;
   + }
   + }
  
   don't you get an IRQ for DMA completion ? If you do, you could be using
   wait_for_completion()
 
  This function is called in interrupt context when buffer is ready or
  free. It initiates DMA to transfer data from IP buffer to memory.
  Hence it waits in busy loop till DMA completes
 
  wait, so you start_dma() before your gadget driver asks you to ?

 in ep_queue driver starts dma transfer from/to IP buffer to/from req-buf.
 If transfer is completed then request is not added to ep request queue
 and returns from ep_queue.
 If transfer is not completed (actual  length) then request is added
 to queue and returns from ep_queue.

 This is wrong. Why wouldn't you give gadget driver the chance to decide
 if it needs to queue the request again or not ?

When does gadget driver decides to queue the same request again?
if -EBUSY is returned from ep_queue or req.status != 0 in completion
routine?

there are cases where ping-pong buffers both are busy. currently this driver
adds request to queue only when buffers are busy. In normal cases request is
processed without adding to queue.

do i need to have another local queue for requests waiting since
buffers are busy?
Or dequeue the request ?


 when buffer processed interrupt occurs, handler starts dma if there is
 request in queue and calls complete call back (when actual == length)
 Hence answer is Yes for some transfers (start dma called from
 interrupt handler not from ep_queue).

 this also seems wrong(-ish).

 1) as Paul pointed out, you can't rely on jiffies if you're calling this
 with IRQs disabled.

 2) you don't really need to wait until DMA finishes its transaction
 before returning from start_dma(), just use the DMA completion IRQ,

 3) I don't see anywhere any sanitizing of arguments, can your DMA really
 handle any alignment/unaligned addresses or should you make sure you're
 getting good arguments?

 You need to work on this a little bit, I guess.

Yes am working on this and will be using seperate ep_ops for ep0  like
drivers/usb/dwc3/gadget.c since ep0 has no dma and ping-pong buffers

Thanks,
Sundeep.B.S.


 --
 balbi
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-17 Thread sundeep subbaraya
Hi Felipe,

On Wed, Apr 16, 2014 at 11:32 PM, Felipe Balbi ba...@ti.com wrote:
 Hi,

 On Wed, Apr 16, 2014 at 04:09:28PM +0530, sundeep subbaraya wrote:
 Hi Felipe,

 On Thu, Apr 3, 2014 at 8:28 PM, Felipe Balbi ba...@ti.com wrote:

  +static int start_dma(struct xusb_ep *ep, u32 src, u32 dst, u32 length)
 
  please prepend this with xudc_, it makes tracing a lot easier.
 
  +{
  + struct xusb_udc *udc;
  + int rc = 0;
  + unsigned long timeout;
  +
  + udc = ep-udc;
  + /*
  +  * Set the addresses in the DMA source and
  +  * destination registers and then set the length
  +  * into the DMA length register.
  +  */
  + udc-write_fn(udc-base_address, XUSB_DMA_DSAR_ADDR_OFFSET, src);
  + udc-write_fn(udc-base_address, XUSB_DMA_DDAR_ADDR_OFFSET, dst);
  + udc-write_fn(udc-base_address, XUSB_DMA_LENGTH_OFFSET, length);
  +
  + /*
  +  * Wait till DMA transaction is complete and
  +  * check whether the DMA transaction was
  +  * successful.
  + */
  + while ((udc-read_fn(ep-udc-base_address + 
  XUSB_DMA_STATUS_OFFSET) 
  + XUSB_DMA_DMASR_BUSY) == XUSB_DMA_DMASR_BUSY) {
  + timeout = jiffies + 1;
  +
  + if (time_after(jiffies, timeout)) {
  + rc = -ETIMEDOUT;
  + goto clean;
  + }
  + }
 
  don't you get an IRQ for DMA completion ? If you do, you could be using
  wait_for_completion()

 This function is called in interrupt context when buffer is ready or
 free. It initiates DMA to transfer data from IP buffer to memory.
 Hence it waits in busy loop till DMA completes

 wait, so you start_dma() before your gadget driver asks you to ?

in ep_queue driver starts dma transfer from/to IP buffer to/from req-buf.
If transfer is completed then request is not added to ep request queue
and returns from ep_queue.
If transfer is not completed (actual  length) then request is added
to queue and returns from ep_queue.
when buffer processed interrupt occurs, handler starts dma if there is
request in queue and calls complete call back (when actual == length)
Hence answer is Yes for some transfers (start dma called from
interrupt handler not from ep_queue).

Thanks,
Sundeep.B.S.

 --
 balbi
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-17 Thread sundeep subbaraya
Hi,

On Thu, Apr 17, 2014 at 1:38 AM, Paul Zimmerman
paul.zimmer...@synopsys.com wrote:
 From: linux-usb-ow...@vger.kernel.org 
 [mailto:linux-usb-ow...@vger.kernel.org] On Behalf Of sundeep subbaraya
 Sent: Wednesday, April 16, 2014 3:39 AM

 Hi Felipe,

 On Thu, Apr 3, 2014 at 8:28 PM, Felipe Balbi ba...@ti.com wrote:

  +static int start_dma(struct xusb_ep *ep, u32 src, u32 dst, u32 length)
 
  please prepend this with xudc_, it makes tracing a lot easier.
 
  +{
  + struct xusb_udc *udc;
  + int rc = 0;
  + unsigned long timeout;
  +
  + udc = ep-udc;
  + /*
  +  * Set the addresses in the DMA source and
  +  * destination registers and then set the length
  +  * into the DMA length register.
  +  */
  + udc-write_fn(udc-base_address, XUSB_DMA_DSAR_ADDR_OFFSET, src);
  + udc-write_fn(udc-base_address, XUSB_DMA_DDAR_ADDR_OFFSET, dst);
  + udc-write_fn(udc-base_address, XUSB_DMA_LENGTH_OFFSET, length);
  +
  + /*
  +  * Wait till DMA transaction is complete and
  +  * check whether the DMA transaction was
  +  * successful.
  + */
  + while ((udc-read_fn(ep-udc-base_address + 
  XUSB_DMA_STATUS_OFFSET) 
  + XUSB_DMA_DMASR_BUSY) == XUSB_DMA_DMASR_BUSY) {
  + timeout = jiffies + 1;
  +
  + if (time_after(jiffies, timeout)) {
  + rc = -ETIMEDOUT;
  + goto clean;
  + }
  + }
 
  don't you get an IRQ for DMA completion ? If you do, you could be using
  wait_for_completion()

 This function is called in interrupt context when buffer is ready or
 free. It initiates
 DMA to transfer data from IP buffer to memory. Hence it waits in busy
 loop till DMA
 completes

 If this function is called in interrupt context, then you can't use
 jiffies for your timeout, since jiffies may not get updated while in
 interrupt context.

Yes. It is obvious that this logic is buggy, will change this.

Thanks,
Sundeep.B.S.

 --
 Paul

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-17 Thread Felipe Balbi
On Thu, Apr 17, 2014 at 03:01:37PM +0530, sundeep subbaraya wrote:
 Hi Felipe,
 
 On Wed, Apr 16, 2014 at 11:32 PM, Felipe Balbi ba...@ti.com wrote:
  Hi,
 
  On Wed, Apr 16, 2014 at 04:09:28PM +0530, sundeep subbaraya wrote:
  Hi Felipe,
 
  On Thu, Apr 3, 2014 at 8:28 PM, Felipe Balbi ba...@ti.com wrote:
 
   +static int start_dma(struct xusb_ep *ep, u32 src, u32 dst, u32 length)
  
   please prepend this with xudc_, it makes tracing a lot easier.
  
   +{
   + struct xusb_udc *udc;
   + int rc = 0;
   + unsigned long timeout;
   +
   + udc = ep-udc;
   + /*
   +  * Set the addresses in the DMA source and
   +  * destination registers and then set the length
   +  * into the DMA length register.
   +  */
   + udc-write_fn(udc-base_address, XUSB_DMA_DSAR_ADDR_OFFSET, src);
   + udc-write_fn(udc-base_address, XUSB_DMA_DDAR_ADDR_OFFSET, dst);
   + udc-write_fn(udc-base_address, XUSB_DMA_LENGTH_OFFSET, length);
   +
   + /*
   +  * Wait till DMA transaction is complete and
   +  * check whether the DMA transaction was
   +  * successful.
   + */
   + while ((udc-read_fn(ep-udc-base_address + 
   XUSB_DMA_STATUS_OFFSET) 
   + XUSB_DMA_DMASR_BUSY) == XUSB_DMA_DMASR_BUSY) {
   + timeout = jiffies + 1;
   +
   + if (time_after(jiffies, timeout)) {
   + rc = -ETIMEDOUT;
   + goto clean;
   + }
   + }
  
   don't you get an IRQ for DMA completion ? If you do, you could be using
   wait_for_completion()
 
  This function is called in interrupt context when buffer is ready or
  free. It initiates DMA to transfer data from IP buffer to memory.
  Hence it waits in busy loop till DMA completes
 
  wait, so you start_dma() before your gadget driver asks you to ?
 
 in ep_queue driver starts dma transfer from/to IP buffer to/from req-buf.
 If transfer is completed then request is not added to ep request queue
 and returns from ep_queue.
 If transfer is not completed (actual  length) then request is added
 to queue and returns from ep_queue.

This is wrong. Why wouldn't you give gadget driver the chance to decide
if it needs to queue the request again or not ?

 when buffer processed interrupt occurs, handler starts dma if there is
 request in queue and calls complete call back (when actual == length)
 Hence answer is Yes for some transfers (start dma called from
 interrupt handler not from ep_queue).

this also seems wrong(-ish).

1) as Paul pointed out, you can't rely on jiffies if you're calling this
with IRQs disabled.

2) you don't really need to wait until DMA finishes its transaction
before returning from start_dma(), just use the DMA completion IRQ,

3) I don't see anywhere any sanitizing of arguments, can your DMA really
handle any alignment/unaligned addresses or should you make sure you're
getting good arguments?

You need to work on this a little bit, I guess.

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-16 Thread sundeep subbaraya
Hi Felipe,

On Thu, Apr 3, 2014 at 8:28 PM, Felipe Balbi ba...@ti.com wrote:

 +static int start_dma(struct xusb_ep *ep, u32 src, u32 dst, u32 length)

 please prepend this with xudc_, it makes tracing a lot easier.

 +{
 + struct xusb_udc *udc;
 + int rc = 0;
 + unsigned long timeout;
 +
 + udc = ep-udc;
 + /*
 +  * Set the addresses in the DMA source and
 +  * destination registers and then set the length
 +  * into the DMA length register.
 +  */
 + udc-write_fn(udc-base_address, XUSB_DMA_DSAR_ADDR_OFFSET, src);
 + udc-write_fn(udc-base_address, XUSB_DMA_DDAR_ADDR_OFFSET, dst);
 + udc-write_fn(udc-base_address, XUSB_DMA_LENGTH_OFFSET, length);
 +
 + /*
 +  * Wait till DMA transaction is complete and
 +  * check whether the DMA transaction was
 +  * successful.
 + */
 + while ((udc-read_fn(ep-udc-base_address + XUSB_DMA_STATUS_OFFSET) 
 + XUSB_DMA_DMASR_BUSY) == XUSB_DMA_DMASR_BUSY) {
 + timeout = jiffies + 1;
 +
 + if (time_after(jiffies, timeout)) {
 + rc = -ETIMEDOUT;
 + goto clean;
 + }
 + }

 don't you get an IRQ for DMA completion ? If you do, you could be using
 wait_for_completion()

This function is called in interrupt context when buffer is ready or
free. It initiates
DMA to transfer data from IP buffer to memory. Hence it waits in busy
loop till DMA
completes

Thanks,
Sundeep.B.S.
 --
 balbi
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-16 Thread Felipe Balbi
Hi,

On Wed, Apr 16, 2014 at 04:09:28PM +0530, sundeep subbaraya wrote:
 Hi Felipe,
 
 On Thu, Apr 3, 2014 at 8:28 PM, Felipe Balbi ba...@ti.com wrote:
 
  +static int start_dma(struct xusb_ep *ep, u32 src, u32 dst, u32 length)
 
  please prepend this with xudc_, it makes tracing a lot easier.
 
  +{
  + struct xusb_udc *udc;
  + int rc = 0;
  + unsigned long timeout;
  +
  + udc = ep-udc;
  + /*
  +  * Set the addresses in the DMA source and
  +  * destination registers and then set the length
  +  * into the DMA length register.
  +  */
  + udc-write_fn(udc-base_address, XUSB_DMA_DSAR_ADDR_OFFSET, src);
  + udc-write_fn(udc-base_address, XUSB_DMA_DDAR_ADDR_OFFSET, dst);
  + udc-write_fn(udc-base_address, XUSB_DMA_LENGTH_OFFSET, length);
  +
  + /*
  +  * Wait till DMA transaction is complete and
  +  * check whether the DMA transaction was
  +  * successful.
  + */
  + while ((udc-read_fn(ep-udc-base_address + XUSB_DMA_STATUS_OFFSET) 
  
  + XUSB_DMA_DMASR_BUSY) == XUSB_DMA_DMASR_BUSY) {
  + timeout = jiffies + 1;
  +
  + if (time_after(jiffies, timeout)) {
  + rc = -ETIMEDOUT;
  + goto clean;
  + }
  + }
 
  don't you get an IRQ for DMA completion ? If you do, you could be using
  wait_for_completion()
 
 This function is called in interrupt context when buffer is ready or
 free. It initiates DMA to transfer data from IP buffer to memory.
 Hence it waits in busy loop till DMA completes

wait, so you start_dma() before your gadget driver asks you to ?

-- 
balbi


signature.asc
Description: Digital signature


RE: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-16 Thread Paul Zimmerman
 From: linux-usb-ow...@vger.kernel.org 
 [mailto:linux-usb-ow...@vger.kernel.org] On Behalf Of sundeep subbaraya
 Sent: Wednesday, April 16, 2014 3:39 AM
 
 Hi Felipe,
 
 On Thu, Apr 3, 2014 at 8:28 PM, Felipe Balbi ba...@ti.com wrote:
 
  +static int start_dma(struct xusb_ep *ep, u32 src, u32 dst, u32 length)
 
  please prepend this with xudc_, it makes tracing a lot easier.
 
  +{
  + struct xusb_udc *udc;
  + int rc = 0;
  + unsigned long timeout;
  +
  + udc = ep-udc;
  + /*
  +  * Set the addresses in the DMA source and
  +  * destination registers and then set the length
  +  * into the DMA length register.
  +  */
  + udc-write_fn(udc-base_address, XUSB_DMA_DSAR_ADDR_OFFSET, src);
  + udc-write_fn(udc-base_address, XUSB_DMA_DDAR_ADDR_OFFSET, dst);
  + udc-write_fn(udc-base_address, XUSB_DMA_LENGTH_OFFSET, length);
  +
  + /*
  +  * Wait till DMA transaction is complete and
  +  * check whether the DMA transaction was
  +  * successful.
  + */
  + while ((udc-read_fn(ep-udc-base_address + XUSB_DMA_STATUS_OFFSET) 
  
  + XUSB_DMA_DMASR_BUSY) == XUSB_DMA_DMASR_BUSY) {
  + timeout = jiffies + 1;
  +
  + if (time_after(jiffies, timeout)) {
  + rc = -ETIMEDOUT;
  + goto clean;
  + }
  + }
 
  don't you get an IRQ for DMA completion ? If you do, you could be using
  wait_for_completion()
 
 This function is called in interrupt context when buffer is ready or
 free. It initiates
 DMA to transfer data from IP buffer to memory. Hence it waits in busy
 loop till DMA
 completes

If this function is called in interrupt context, then you can't use
jiffies for your timeout, since jiffies may not get updated while in
interrupt context.

-- 
Paul

N�r��yb�X��ǧv�^�)޺{.n�+{��^n�r���z���h����G���h�(�階�ݢj���m��z�ޖ���f���h���~�m�

Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-07 Thread sundeep subbaraya
Hi Michal,

On Thu, Apr 3, 2014 at 8:53 PM, Michal Simek mon...@monstr.eu wrote:
 +struct xusb_udc {
 +struct usb_gadget gadget;
 +struct xusb_ep ep[8];
 +struct usb_gadget_driver *driver;
 +struct cmdbuf ch9cmd;
 +u32 usb_state;
 +u32 remote_wkp;
 +unsigned int (*read_fn)(void __iomem *);
 +void (*write_fn)(void __iomem *, u32, u32);

 why do you need these to be function pointers ? Because of endianness ?
 generic readl()/writel() already take care of that.

 readl from asm-generic/io.h is converting value from little endian IO
 to cpu endianness.
 This IP exists also in big endian version.
 It means we have to support all possible combinations.
 IP little and reading it on little or big endian CPU
 IP big and reading it on little or big endian CPU.

 Look below.

 +spin_lock_init(udc-lock);
 +
 +/* Check for IP endianness */
 +udc-write_fn = xudc_write32_be;
 +udc-read_fn = xudc_read32_be;
 +udc-write_fn(udc-base_address, XUSB_TESTMODE_OFFSET, TEST_J);
 +if ((udc-read_fn(udc-base_address + XUSB_TESTMODE_OFFSET))
 +!= TEST_J) {
 +udc-write_fn = xudc_write32;
 +udc-read_fn = xudc_read32;
 +}

 hmm... isn't there a configuration register to check this out ?

 Sundeep can tell us if there is any configuration register but
 I don't think so in connection to my experience with Xilinx soft IPs.


Yes, there is no configuration register for endianess.

Thanks,
Sundeep.

 Endian detection directly on IP itself came from my discussion
 on drivers/spi/spi-xilinx.c that this is only one way how to do it.

 Thanks,
 Michal

 --
 Michal Simek, Ing. (M.Eng), OpenPGP - KeyID: FE3D1F91
 w: www.monstr.eu p: +42-0-721842854
 Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
 Maintainer of Linux kernel - Xilinx Zynq ARM architecture
 Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] usb: gadget: Add xilinx axi usb2 device support

2014-04-03 Thread Michal Simek
 +struct xusb_udc {
 +struct usb_gadget gadget;
 +struct xusb_ep ep[8];
 +struct usb_gadget_driver *driver;
 +struct cmdbuf ch9cmd;
 +u32 usb_state;
 +u32 remote_wkp;
 +unsigned int (*read_fn)(void __iomem *);
 +void (*write_fn)(void __iomem *, u32, u32);
 
 why do you need these to be function pointers ? Because of endianness ?
 generic readl()/writel() already take care of that.

readl from asm-generic/io.h is converting value from little endian IO
to cpu endianness.
This IP exists also in big endian version.
It means we have to support all possible combinations.
IP little and reading it on little or big endian CPU
IP big and reading it on little or big endian CPU.

Look below.

 +spin_lock_init(udc-lock);
 +
 +/* Check for IP endianness */
 +udc-write_fn = xudc_write32_be;
 +udc-read_fn = xudc_read32_be;
 +udc-write_fn(udc-base_address, XUSB_TESTMODE_OFFSET, TEST_J);
 +if ((udc-read_fn(udc-base_address + XUSB_TESTMODE_OFFSET))
 +!= TEST_J) {
 +udc-write_fn = xudc_write32;
 +udc-read_fn = xudc_read32;
 +}
 
 hmm... isn't there a configuration register to check this out ?

Sundeep can tell us if there is any configuration register but
I don't think so in connection to my experience with Xilinx soft IPs.

Endian detection directly on IP itself came from my discussion
on drivers/spi/spi-xilinx.c that this is only one way how to do it.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP - KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform




signature.asc
Description: OpenPGP digital signature