Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Jun 2009 19:12:19 +0200
From:      Hans Petter Selasky <hselasky@c2i.net>
To:        Alexandr Rybalko <ray@dlink.ua>
Cc:        freebsd-usb@freebsd.org, Rafal Jaworowski <raj@semihalf.com>, thompsa@freebsd.org
Subject:   Re: CPU Cache and busdma usage in USB
Message-ID:  <200906231912.20741.hselasky@c2i.net>
In-Reply-To: <20090623121129.d18492a3.ray@dlink.ua>
References:  <200906231035.43096.kosmo@semihalf.com> <20090623121129.d18492a3.ray@dlink.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tuesday 23 June 2009 11:11:29 Alexandr Rybalko wrote:
> On Tue, 23 Jun 2009 10:35:42 +0200
>
> Piotr Zi=C4=99cik <kosmo@semihalf.com> wrote:
> >> While bringing up EHCI  (8-CURRENT, new USB stack) on ARM machine we
> >> have found cache-related problem in the USB stack.
> >>
> >> The usb_pc_cpu_flush() and usb_pc_cpu_invalidate() functions are used =
to
> >> flush/invalidate CPU caches in various places in USB code. Internally,
> >> the functions are implemented using bus_dmamap_sync(). In our case, on
> >> ARM machine, flags passed to the bus_dmamap_sync() function did not
> >> correspond with requested operation. We have fixed the problem by
> >> changing flags passed to the bus_dmamap_sync() function (see attached
> >> patch).
> >>
> >> My question is about general idea of bus_dma usage for cache operation=
s.
> >> In my opinion we should not rely on bus_dmamap_sync() behaviour as this
> >> function may do different things on different architectures.  This not
> >> always works as expected, which is clearly visible in our case. Better
> >> solution is to use cpu-specific functions implementing cache operation=
s.
> >> Please comment on why CPU-specific functions are not used...
> >>
> >> Patch fixing our problem:
> >> diff --git a/sys/dev/usb/usb_busdma.c b/sys/dev/usb/usb_busdma.c
> >> index 3d6a5be..69a6fff 100644
> >> --- a/sys/dev/usb/usb_busdma.c
> >> +++ b/sys/dev/usb/usb_busdma.c
> >> @@ -658,8 +658,7 @@ usb_pc_cpu_invalidate(struct usb_page_cache *pc)
> >>                 /* nothing has been loaded into this page cache! */
> >>                 return;
> >>         }
> >> -       bus_dmamap_sync(pc->tag, pc->map,
> >> -           BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
> >> +       bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD);
> >>  }
> >>
> >>=20
> >> /*--------------------------------------------------------------------=
=2D-
> >>--* @@ -672,8 +671,7 @@ usb_pc_cpu_flush(struct usb_page_cache *pc) /*
> >> nothing has been loaded into this page cache! */ return;
> >>         }
> >> -       bus_dmamap_sync(pc->tag, pc->map,
> >> -           BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
> >> +       bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE);
> >>  }
> >>
> >>=20
> >> /*--------------------------------------------------------------------=
=2D-
> >>--*
> >>

>
> Great thanks Piotr!
> I work on MIPS BCM5354 and BCM5836 and after apply your patch USB work
> correct.

We are currently investigating if your patch is correct. Thanks for your pa=
tch=20
suggestion!

BTW: Have you tried out the new device side mode support in the FreeBSD 8-
current USB stack?

=2D-HPS




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906231912.20741.hselasky>