Re: [PATCH RFC] usb: musb: fail unaligned DMA transfers on v1.8 and above

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

 



Cc Hema

2010/10/31 Anand Gadiyar <gadiyar@xxxxxx>:
> The Inventra DMA engine in version 1.8 and later of the MUSB
> controller cannot handle DMA addresses that are not aligned
> to a 4 byte boundary. It ends up ignoring the last two bits
> programmed in the DMA_ADDR register. This is a deliberate
> design change in the controller and is documented in the
> programming guide.
>
> Earlier versions of the controller could handle these
> accesses just fine.
>
> Fail dma_channel_program if we see an unaligned address when
> using the newer controllers, so that the caller can carry out
> the transfer using PIO mode.
> (Current callers already have this backup path in place).
>
> Signed-off-by: Anand Gadiyar <gadiyar@xxxxxx>
> Cc: Felipe Balbi <balbi@xxxxxx>
> Cc: Ming Lei <tom.leiming@xxxxxxxxx>
> Cc: Ajay Kumar Gupta <ajay.gupta@xxxxxx>
> Cc: Mike Frysinger <vapier@xxxxxxxxxx>

Tested-by: Ming Lei <tom.leiming@xxxxxxxxx>

This patch is verified OK about g_ether function on beagle xM board,
but the revised patch "usb: musb: gadget: Unmapping the dma buffer
when switching to PIO mode" [1] should be applied first.

> ---
> Patch based on linux-next as of 20101029.
>
> I believe Blackfin is also affected by this, but I'm not sure how
> they're working around this. Mike?

MUSB on Blackfin will fallback to PIO too, so no any working around
for it, right?

>
>  drivers/usb/musb/musbhsdma.c |   14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> Index: mainline/drivers/usb/musb/musbhsdma.c
> ===================================================================
> --- mainline.orig/drivers/usb/musb/musbhsdma.c
> +++ mainline/drivers/usb/musb/musbhsdma.c
> @@ -158,6 +158,8 @@ static int dma_channel_program(struct dm
>                                dma_addr_t dma_addr, u32 len)
>  {
>        struct musb_dma_channel *musb_channel = channel->private_data;
> +       struct musb_dma_controller *controller = musb_channel->controller;
> +       struct musb *musb = controller->private_data;
>
>        DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
>                musb_channel->epnum,
> @@ -167,6 +169,18 @@ static int dma_channel_program(struct dm
>        BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
>                channel->status == MUSB_DMA_STATUS_BUSY);
>
> +       /*
> +        * The DMA engine in RTL1.8 and above cannot handle
> +        * DMA addresses that are not aligned to a 4 byte boundary.
> +        * It ends up masking the last two bits of the address
> +        * programmed in DMA_ADDR.
> +        *
> +        * Fail such DMA transfers, so that the backup PIO mode
> +        * can carry out the transfer
> +        */
> +       if ((musb->hwvers >= MUSB_HWVERS_1800) && (dma_addr %4))
> +               return false;
> +
>        channel->actual_len = 0;
>        musb_channel->start_addr = dma_addr;
>        musb_channel->len = len;
>

[1], http://marc.info/?l=linux-usb&m=128532510705381&w=2

-- 
Lei Ming
--
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


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

  Powered by Linux