2010-04-07 09:06:36

by Daniel Mack

[permalink] [raw]
Subject: USB transfer_buffer allocations on 64bit systems

Hi,

I was pointed to https://bugzilla.kernel.org/show_bug.cgi?id=15580 by
Pedro Ribeiro, and unfortunately I'm pretty late in the game. I wasn't
aware of that thread until yesterday.

While the report is quite confusing, the reason seams pretty clear to me
as I've been thru quite some time-demanding debugging of a very similar
issue on Mac OS X. But I'm not totally sure whether we really hit the
same issue here, so I'd like to have your opinions first.

The problem is appearantly the way the transfer buffer is allocated in
the drivers. In the snd-usb-caiaq driver, I used kzalloc() to get memory
which works fine on 32bit systems. On x86_64, however, it seems that
kzalloc() hands out memory beyond the 32bit addressable boundary, which
the DMA controller of the 32bit PCI-connected EHCI controller is unable
to write to or read from. Am I correct on this conclusion?

Depending on the condition of the memory management, things might work
or not, and especially right after a reboot, there's a better chance to
get lower memory.

The fix is to use usb_buffer_alloc() for that purpose which ensures
memory that is suitable for DMA. And on x86_64, this also means that the
upper 32 bits of the address returned are all 0's.

If what I've stated is true, there are quite some more drivers affected
by this issue. I collected a list of places where similar fixes are
needed, and I can send patches if I get a thumbs-up.

Pedro is currently testing a patch I sent out yesterday.

Thanks,
Daniel


2010-04-07 14:59:50

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 7 Apr 2010, Daniel Mack wrote:

> Hi,
>
> I was pointed to https://bugzilla.kernel.org/show_bug.cgi?id=15580 by
> Pedro Ribeiro, and unfortunately I'm pretty late in the game. I wasn't
> aware of that thread until yesterday.
>
> While the report is quite confusing, the reason seams pretty clear to me
> as I've been thru quite some time-demanding debugging of a very similar
> issue on Mac OS X. But I'm not totally sure whether we really hit the
> same issue here, so I'd like to have your opinions first.
>
> The problem is appearantly the way the transfer buffer is allocated in
> the drivers. In the snd-usb-caiaq driver, I used kzalloc() to get memory
> which works fine on 32bit systems. On x86_64, however, it seems that
> kzalloc() hands out memory beyond the 32bit addressable boundary, which
> the DMA controller of the 32bit PCI-connected EHCI controller is unable
> to write to or read from. Am I correct on this conclusion?

That seems like the right answer. You are correct that an EHCI
controller capable only of 32-bit memory accesses would not be able to
use a buffer above the 4 GB line.

> Depending on the condition of the memory management, things might work
> or not, and especially right after a reboot, there's a better chance to
> get lower memory.
>
> The fix is to use usb_buffer_alloc() for that purpose which ensures
> memory that is suitable for DMA. And on x86_64, this also means that the
> upper 32 bits of the address returned are all 0's.

That is not a good fix. usb_buffer_alloc() provides coherent memory,
which is not what we want. I believe the correct fix is to specify the
GFP_DMA32 flag in the kzalloc() call.

Of course, some EHCI hardware _is_ capable of using 64-bit addresses.
But not all, and other controller types aren't. In principle we could
create a new allocation routine, which would take a pointer to the USB
bus as an additional argument and use it to decide whether the memory
needs to lie below 4 GB. I'm not sure adding this extra complexity
would be worthwhile.

> If what I've stated is true, there are quite some more drivers affected
> by this issue.

Practically every USB driver, I should think. And maybe a lot of
non-USB drivers too.

> I collected a list of places where similar fixes are
> needed, and I can send patches if I get a thumbs-up.
>
> Pedro is currently testing a patch I sent out yesterday.

Good work -- it certainly would have taken me a long time to figure
this out.

Alan Stern

2010-04-07 15:11:35

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 07, 2010 at 10:59:47AM -0400, Alan Stern wrote:
> On Wed, 7 Apr 2010, Daniel Mack wrote:
> > Depending on the condition of the memory management, things might work
> > or not, and especially right after a reboot, there's a better chance to
> > get lower memory.
> >
> > The fix is to use usb_buffer_alloc() for that purpose which ensures
> > memory that is suitable for DMA. And on x86_64, this also means that the
> > upper 32 bits of the address returned are all 0's.
>
> That is not a good fix. usb_buffer_alloc() provides coherent memory,
> which is not what we want. I believe the correct fix is to specify the
> GFP_DMA32 flag in the kzalloc() call.
>
> Of course, some EHCI hardware _is_ capable of using 64-bit addresses.
> But not all, and other controller types aren't. In principle we could
> create a new allocation routine, which would take a pointer to the USB
> bus as an additional argument and use it to decide whether the memory
> needs to lie below 4 GB. I'm not sure adding this extra complexity
> would be worthwhile.

Well, I thought this is exactly what the usb_buffer_alloc() abstraction
functions are there for. We already pass a pointer to a struct
usb_device, so the routine knows which host controller it operates on.
So we can safely dispatch all the magic inside this function, no?

If not, I would rather introduce a new function than adding GFP_ flags
to all existing drivers.

I vote for a clean solution, a fixup of existing implementations and
a clear note about how to allocate buffers for USB drivers. I believe
faulty allocations of this kind can explain quite a lot of problems on
x86_64 machines.

> > If what I've stated is true, there are quite some more drivers affected
> > by this issue.
>
> Practically every USB driver, I should think. And maybe a lot of
> non-USB drivers too.

I found many such problems in drivers/media/{dvb,video},
drivers/usb/serial, sound/usb and even in the USB core. If we agree on
how to fix that nicely, I can take some of them.

Daniel

2010-04-07 15:32:00

by Greg KH

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 07, 2010 at 05:11:25PM +0200, Daniel Mack wrote:
> On Wed, Apr 07, 2010 at 10:59:47AM -0400, Alan Stern wrote:
> > On Wed, 7 Apr 2010, Daniel Mack wrote:
> > > Depending on the condition of the memory management, things might work
> > > or not, and especially right after a reboot, there's a better chance to
> > > get lower memory.
> > >
> > > The fix is to use usb_buffer_alloc() for that purpose which ensures
> > > memory that is suitable for DMA. And on x86_64, this also means that the
> > > upper 32 bits of the address returned are all 0's.
> >
> > That is not a good fix. usb_buffer_alloc() provides coherent memory,
> > which is not what we want. I believe the correct fix is to specify the
> > GFP_DMA32 flag in the kzalloc() call.
> >
> > Of course, some EHCI hardware _is_ capable of using 64-bit addresses.
> > But not all, and other controller types aren't. In principle we could
> > create a new allocation routine, which would take a pointer to the USB
> > bus as an additional argument and use it to decide whether the memory
> > needs to lie below 4 GB. I'm not sure adding this extra complexity
> > would be worthwhile.
>
> Well, I thought this is exactly what the usb_buffer_alloc() abstraction
> functions are there for. We already pass a pointer to a struct
> usb_device, so the routine knows which host controller it operates on.
> So we can safely dispatch all the magic inside this function, no?

Hm, yeah, I thought that is what it was for too. If not, why can't we
use it like this?

> If not, I would rather introduce a new function than adding GFP_ flags
> to all existing drivers.

I agree.

> I vote for a clean solution, a fixup of existing implementations and
> a clear note about how to allocate buffers for USB drivers. I believe
> faulty allocations of this kind can explain quite a lot of problems on
> x86_64 machines.

Yeah, I really don't want to have to change every driver in different
ways just depending on if someone thinks it is going to need to run on
this wierd hardware.

Alan, any objection to just using usb_buffer_alloc() for every driver?
Or is that too much overhead?

thanks,

greg k-h

2010-04-07 15:35:57

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 07, 2010 at 08:31:54AM -0700, Greg KH wrote:
> On Wed, Apr 07, 2010 at 05:11:25PM +0200, Daniel Mack wrote:
> > I vote for a clean solution, a fixup of existing implementations and
> > a clear note about how to allocate buffers for USB drivers. I believe
> > faulty allocations of this kind can explain quite a lot of problems on
> > x86_64 machines.
>
> Yeah, I really don't want to have to change every driver in different
> ways just depending on if someone thinks it is going to need to run on
> this wierd hardware.
>
> Alan, any objection to just using usb_buffer_alloc() for every driver?
> Or is that too much overhead?

FWIW, most drivers I've seen in the past hours use a wild mix of
kmalloc(), kzalloc(), kcalloc() and usb_buffer_alloc(). That should
really be unified.

Daniel

2010-04-07 15:46:19

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 7 Apr 2010, Daniel Mack wrote:

> > > The fix is to use usb_buffer_alloc() for that purpose which ensures
> > > memory that is suitable for DMA. And on x86_64, this also means that the
> > > upper 32 bits of the address returned are all 0's.
> >
> > That is not a good fix. usb_buffer_alloc() provides coherent memory,
> > which is not what we want. I believe the correct fix is to specify the
> > GFP_DMA32 flag in the kzalloc() call.
> >
> > Of course, some EHCI hardware _is_ capable of using 64-bit addresses.
> > But not all, and other controller types aren't. In principle we could
> > create a new allocation routine, which would take a pointer to the USB
> > bus as an additional argument and use it to decide whether the memory
> > needs to lie below 4 GB. I'm not sure adding this extra complexity
> > would be worthwhile.
>
> Well, I thought this is exactly what the usb_buffer_alloc() abstraction
> functions are there for. We already pass a pointer to a struct
> usb_device, so the routine knows which host controller it operates on.
> So we can safely dispatch all the magic inside this function, no?

No. It says so right in the title line of the kerneldoc:

* usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP

That is not what people want when they call kzalloc or kmalloc.

> If not, I would rather introduce a new function than adding GFP_ flags
> to all existing drivers.

All right. But there would have to be _two_ new functions: one acting
like kmalloc and another acting like kzalloc. I guess they should take
a pointer to struct usb_device as an argument, like usb_buffer_alloc.

> I vote for a clean solution, a fixup of existing implementations and
> a clear note about how to allocate buffers for USB drivers. I believe
> faulty allocations of this kind can explain quite a lot of problems on
> x86_64 machines.

There is one awkward aspect of usb_buffer_alloc which perhaps could
be fixed at the same time. Under some conditions (for example, if the
controller needs to use internal bounce buffers) it will return
ordinary memory obtained using kmalloc rather than consistent memory.
But it doesn't tell the caller when it has done so, and consequently
the caller will always specify URB_NO_TRANSFER_DMA_MAP when using the
buffer. The proper flag to use should be returned to the caller.

Or alternatively, instead of allocating regular memory the routine
could simply fail. Then the caller would be responsible for checking
and using regular memory instead of dma-consistent memory. Of course,
that would put an even larger burden on the caller than just forcing it
to keep track of what flag to use.

> > > If what I've stated is true, there are quite some more drivers affected
> > > by this issue.
> >
> > Practically every USB driver, I should think. And maybe a lot of
> > non-USB drivers too.
>
> I found many such problems in drivers/media/{dvb,video},
> drivers/usb/serial, sound/usb and even in the USB core. If we agree on
> how to fix that nicely, I can take some of them.

I guess we could rename usb_buffer_alloc(). A more accurate name would
be something like usb_alloc_consistent() (except for the fact that
the routine falls back to regular memory if the controller can't use
consistent memory.) Then we could have usb_malloc() and usb_zalloc()
in addition.

Alan Stern

2010-04-07 15:51:46

by Greg KH

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 07, 2010 at 05:35:51PM +0200, Daniel Mack wrote:
> On Wed, Apr 07, 2010 at 08:31:54AM -0700, Greg KH wrote:
> > On Wed, Apr 07, 2010 at 05:11:25PM +0200, Daniel Mack wrote:
> > > I vote for a clean solution, a fixup of existing implementations and
> > > a clear note about how to allocate buffers for USB drivers. I believe
> > > faulty allocations of this kind can explain quite a lot of problems on
> > > x86_64 machines.
> >
> > Yeah, I really don't want to have to change every driver in different
> > ways just depending on if someone thinks it is going to need to run on
> > this wierd hardware.
> >
> > Alan, any objection to just using usb_buffer_alloc() for every driver?
> > Or is that too much overhead?
>
> FWIW, most drivers I've seen in the past hours use a wild mix of
> kmalloc(), kzalloc(), kcalloc() and usb_buffer_alloc(). That should
> really be unified.

Yes, if it is necessary that we have to handle this type of crappy
hardware, then it all needs to be unified. Or at least unified into 2
types of calls, one that needs the bounce buffer fun (what
usb_buffer_alloc() does today), and one that doesn't (usb_kzalloc()
perhaps?)

thanks,

greg k-h

2010-04-07 15:55:22

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 7 Apr 2010, Greg KH wrote:

> Yeah, I really don't want to have to change every driver in different
> ways just depending on if someone thinks it is going to need to run on
> this wierd hardware.

It's not weird hardware, as far as I know. It's just a 64-bit system
with a 32-bit USB host controller.

(And remember, while there are 64-bit EHCI controllers, there are not
any 64-bit OHCI or UHCI controllers. So whenever somebody plugs a
full-speed or low-speed device into a 64-bit machine, they will face
this problem. It's like the old problem of ISA devices that could
only do DMA to addresses in the first 16 MB of memory -- what the
original GFP_DMA flag was intended for.)

> Alan, any objection to just using usb_buffer_alloc() for every driver?
> Or is that too much overhead?

I don't know what the overhead is. But usb_buffer_alloc() requires the
caller to keep track of the buffer's DMA address, so it's not a simple
plug-in replacement. In addition, the consistent memory that
usb_buffer_alloc() provides is a scarce resource on some platforms.

Writing new functions is the way to go.

Alan Stern

2010-04-07 16:04:35

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 7 Apr 2010, Greg KH wrote:

> > FWIW, most drivers I've seen in the past hours use a wild mix of
> > kmalloc(), kzalloc(), kcalloc() and usb_buffer_alloc(). That should
> > really be unified.

Well, kcalloc can easily be replaced by kzalloc, right? Or the
equivalent.

The extra overhead of initializing the memory to 0 isn't present in
kmalloc, so we need to maintain the distinction between kmalloc and
kzalloc.

However usb_buffer_alloc is fundmentally different from all the others.

> Yes, if it is necessary that we have to handle this type of crappy
> hardware, then it all needs to be unified. Or at least unified into 2
> types of calls, one that needs the bounce buffer fun (what
> usb_buffer_alloc() does today), and one that doesn't (usb_kzalloc()
> perhaps?)

usb_buffer_alloc has very little to do with bounce buffers. Its
purpose is to allocate dma-consistent memory, that it, memory which
does not need to be mapped for DMA before each I/O operation and
unmapped afterward.

The mapping and unmapping operations aren't extremely time consuming,
so in general it makes sense to avoid them only when the _same_ buffer
is going to be used for many I/O operations during a short period of
time. For instance, it makes sense for audio and video, where all the
data streams through a small set of buffers arranged in a ring.

But for most other uses it makes no sense. Especially since some
platforms have limited amounts of consistent memory available.

Alan Stern

2010-04-07 16:16:10

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 07, 2010 at 11:55:19AM -0400, Alan Stern wrote:
> On Wed, 7 Apr 2010, Greg KH wrote:
>
> > Alan, any objection to just using usb_buffer_alloc() for every driver?
> > Or is that too much overhead?
>
> I don't know what the overhead is. But usb_buffer_alloc() requires the
> caller to keep track of the buffer's DMA address, so it's not a simple
> plug-in replacement. In addition, the consistent memory that
> usb_buffer_alloc() provides is a scarce resource on some platforms.
>
> Writing new functions is the way to go.

Ok, I'll write some dummies for usb_malloc() and usb_zalloc() which
will just call kmalloc() with GFP_DMA32 for now. And while at it,
usb_alloc_buffer() will be renamed to usb_alloc_consistent(). Then I'll
try to clean up all existing drivers to use this new interface and
follow the changes.

In a next step, we should fine-tune when GFP_DMA32 is really needed.
And I'll leave all occurances of usb_alloc_consistent() as they are now.

Does that sound ok?

Thanks,
Daniel

2010-04-07 16:47:12

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 7 Apr 2010, Daniel Mack wrote:

> Ok, I'll write some dummies for usb_malloc() and usb_zalloc() which
> will just call kmalloc() with GFP_DMA32 for now. And while at it,
> usb_alloc_buffer() will be renamed to usb_alloc_consistent(). Then I'll
> try to clean up all existing drivers to use this new interface and
> follow the changes.
>
> In a next step, we should fine-tune when GFP_DMA32 is really needed.
> And I'll leave all occurances of usb_alloc_consistent() as they are now.
>
> Does that sound ok?

Yes, that should work out well.

Alan Stern

2010-04-07 16:56:35

by Oliver Neukum

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

Am Mittwoch, 7. April 2010 16:59:47 schrieb Alan Stern:
> > The fix is to use usb_buffer_alloc() for that purpose which ensures
> > memory that is suitable for DMA. And on x86_64, this also means that the
> > upper 32 bits of the address returned are all 0's.
>
> That is not a good fix. usb_buffer_alloc() provides coherent memory,
> which is not what we want. I believe the correct fix is to specify the
> GFP_DMA32 flag in the kzalloc() call.
>
> Of course, some EHCI hardware is capable of using 64-bit addresses.
> But not all, and other controller types aren't. In principle we could
> create a new allocation routine, which would take a pointer to the USB
> bus as an additional argument and use it to decide whether the memory
> needs to lie below 4 GB. I'm not sure adding this extra complexity
> would be worthwhile.

What about XHCI? Do you really want to limit it to 32bits?

Regards
Oliver

2010-04-07 17:00:13

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 07, 2010 at 06:54:55PM +0200, Oliver Neukum wrote:
> Am Mittwoch, 7. April 2010 16:59:47 schrieb Alan Stern:
> > > The fix is to use usb_buffer_alloc() for that purpose which ensures
> > > memory that is suitable for DMA. And on x86_64, this also means that the
> > > upper 32 bits of the address returned are all 0's.
> >
> > That is not a good fix. usb_buffer_alloc() provides coherent memory,
> > which is not what we want. I believe the correct fix is to specify the
> > GFP_DMA32 flag in the kzalloc() call.
> >
> > Of course, some EHCI hardware is capable of using 64-bit addresses.
> > But not all, and other controller types aren't. In principle we could
> > create a new allocation routine, which would take a pointer to the USB
> > bus as an additional argument and use it to decide whether the memory
> > needs to lie below 4 GB. I'm not sure adding this extra complexity
> > would be worthwhile.
>
> What about XHCI? Do you really want to limit it to 32bits?

No. Once we have the abstraction functions, we can well decide what to
do in there, depending on the actual controller we're running on.

Daniel

2010-04-07 17:52:34

by Takashi Iwai

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

At Wed, 7 Apr 2010 11:55:19 -0400 (EDT),
Alan Stern wrote:
>
> On Wed, 7 Apr 2010, Greg KH wrote:
>
> > Yeah, I really don't want to have to change every driver in different
> > ways just depending on if someone thinks it is going to need to run on
> > this wierd hardware.
>
> It's not weird hardware, as far as I know. It's just a 64-bit system
> with a 32-bit USB host controller.
>
> (And remember, while there are 64-bit EHCI controllers, there are not
> any 64-bit OHCI or UHCI controllers. So whenever somebody plugs a
> full-speed or low-speed device into a 64-bit machine, they will face
> this problem. It's like the old problem of ISA devices that could
> only do DMA to addresses in the first 16 MB of memory -- what the
> original GFP_DMA flag was intended for.)
>
> > Alan, any objection to just using usb_buffer_alloc() for every driver?
> > Or is that too much overhead?
>
> I don't know what the overhead is. But usb_buffer_alloc() requires the
> caller to keep track of the buffer's DMA address, so it's not a simple
> plug-in replacement. In addition, the consistent memory that
> usb_buffer_alloc() provides is a scarce resource on some platforms.

Yeah, also the area is aligned to kernel pages, and it may be much
bigger than the requested (power-of-two). If not needed, we should
avoid it.


thanks,

Takashi

2010-04-07 17:55:22

by Takashi Iwai

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

At Wed, 7 Apr 2010 18:16:03 +0200,
Daniel Mack wrote:
>
> On Wed, Apr 07, 2010 at 11:55:19AM -0400, Alan Stern wrote:
> > On Wed, 7 Apr 2010, Greg KH wrote:
> >
> > > Alan, any objection to just using usb_buffer_alloc() for every driver?
> > > Or is that too much overhead?
> >
> > I don't know what the overhead is. But usb_buffer_alloc() requires the
> > caller to keep track of the buffer's DMA address, so it's not a simple
> > plug-in replacement. In addition, the consistent memory that
> > usb_buffer_alloc() provides is a scarce resource on some platforms.
> >
> > Writing new functions is the way to go.
>
> Ok, I'll write some dummies for usb_malloc() and usb_zalloc() which
> will just call kmalloc() with GFP_DMA32 for now.

Can't we provide only zalloc() variant? Zero'ing doesn't cost much,
and the buffer allocation shouldn't be called too often.

> And while at it,
> usb_alloc_buffer() will be renamed to usb_alloc_consistent().

Most of recent functions are named with "coherent".


thanks,

Takashi

2010-04-07 17:59:42

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 07, 2010 at 07:55:20PM +0200, Takashi Iwai wrote:
> At Wed, 7 Apr 2010 18:16:03 +0200,
> Daniel Mack wrote:
> >
> > On Wed, Apr 07, 2010 at 11:55:19AM -0400, Alan Stern wrote:
> > > On Wed, 7 Apr 2010, Greg KH wrote:
> > >
> > > > Alan, any objection to just using usb_buffer_alloc() for every driver?
> > > > Or is that too much overhead?
> > >
> > > I don't know what the overhead is. But usb_buffer_alloc() requires the
> > > caller to keep track of the buffer's DMA address, so it's not a simple
> > > plug-in replacement. In addition, the consistent memory that
> > > usb_buffer_alloc() provides is a scarce resource on some platforms.
> > >
> > > Writing new functions is the way to go.
> >
> > Ok, I'll write some dummies for usb_malloc() and usb_zalloc() which
> > will just call kmalloc() with GFP_DMA32 for now.
>
> Can't we provide only zalloc() variant? Zero'ing doesn't cost much,
> and the buffer allocation shouldn't be called too often.
>
> > And while at it,
> > usb_alloc_buffer() will be renamed to usb_alloc_consistent().
>
> Most of recent functions are named with "coherent".

I agree to both points, will do so unless anyone has a harsh opinion
about that.

Another thing: I guess we don't need a corresponding free() function
that just calls kfree(), right? Or should we introduce it now to be
flexible for future extensions?

Daniel

2010-04-07 18:06:12

by Takashi Iwai

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

At Wed, 7 Apr 2010 19:59:35 +0200,
Daniel Mack wrote:
>
> On Wed, Apr 07, 2010 at 07:55:20PM +0200, Takashi Iwai wrote:
> > At Wed, 7 Apr 2010 18:16:03 +0200,
> > Daniel Mack wrote:
> > >
> > > On Wed, Apr 07, 2010 at 11:55:19AM -0400, Alan Stern wrote:
> > > > On Wed, 7 Apr 2010, Greg KH wrote:
> > > >
> > > > > Alan, any objection to just using usb_buffer_alloc() for every driver?
> > > > > Or is that too much overhead?
> > > >
> > > > I don't know what the overhead is. But usb_buffer_alloc() requires the
> > > > caller to keep track of the buffer's DMA address, so it's not a simple
> > > > plug-in replacement. In addition, the consistent memory that
> > > > usb_buffer_alloc() provides is a scarce resource on some platforms.
> > > >
> > > > Writing new functions is the way to go.
> > >
> > > Ok, I'll write some dummies for usb_malloc() and usb_zalloc() which
> > > will just call kmalloc() with GFP_DMA32 for now.
> >
> > Can't we provide only zalloc() variant? Zero'ing doesn't cost much,
> > and the buffer allocation shouldn't be called too often.
> >
> > > And while at it,
> > > usb_alloc_buffer() will be renamed to usb_alloc_consistent().
> >
> > Most of recent functions are named with "coherent".
>
> I agree to both points, will do so unless anyone has a harsh opinion
> about that.
>
> Another thing: I guess we don't need a corresponding free() function
> that just calls kfree(), right? Or should we introduce it now to be
> flexible for future extensions?

Well, I would implement the corresponding free. It could be simply
a macro calling kfree(), but it's saner to provide it for API
uniformity, IMO.


thanks,

Takashi

2010-04-07 19:13:13

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 7 Apr 2010, Takashi Iwai wrote:

> > Ok, I'll write some dummies for usb_malloc() and usb_zalloc() which
> > will just call kmalloc() with GFP_DMA32 for now.
>
> Can't we provide only zalloc() variant? Zero'ing doesn't cost much,
> and the buffer allocation shouldn't be called too often.

Linus specifically requested us to avoid using kzalloc in usbfs. I
can't find the message in the email archives, but Greg KH should be
able to confirm it.

As long as we're imitating kmalloc for one use, we might as well make
it available to all.

> > And while at it,
> > usb_alloc_buffer() will be renamed to usb_alloc_consistent().
>
> Most of recent functions are named with "coherent".

Yes, the terminology got a little confused between the PCI and DMA
realms. I agree, "coherent" is better.

BTW, although some EHCI controllers may support 64-bit DMA, the driver
contains this:

if (HCC_64BIT_ADDR(hcc_params)) {
ehci_writel(ehci, 0, &ehci->regs->segment);
#if 0
// this is deeply broken on almost all architectures
if (!dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)))
ehci_info(ehci, "enabled 64bit DMA\n");
#endif
}

I don't know if the comment is still true, but until the "#if 0" is
removed, ehci-hcd won't make use of 64-bit DMA.

Note also that just before the lines above, ehci-hcd.c contains this
comment:

* pci_pool consistent memory always uses segment zero.

(Nowadays the driver uses dma_pool, not pci_pool.) As far as I can
tell, this comment isn't true on 64-bit systems, but nevertheless,
ehci-hcd relies on it. Of course it _is_ true for devices whose DMA
mask indicates they can't use memory above 4 GB -- but if ehci-hcd is
changed to enlarge the DMA mask then how do we force dma_pool memory to
lie below 4 GB?

[Actually it isn't _really_ necessary for the dma_pool to lie below 4
GB. But ehci-hcd allocates several pools, and it _is_ necessary for
all of them to lie in the _same_ 4 GB segment. The easiest way to do
that is to put them all in segment 0.]

Alan Stern

2010-04-07 23:55:31

by Robert Hancock

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 04/07/2010 08:59 AM, Alan Stern wrote:
> On Wed, 7 Apr 2010, Daniel Mack wrote:
>
>> Hi,
>>
>> I was pointed to https://bugzilla.kernel.org/show_bug.cgi?id=15580 by
>> Pedro Ribeiro, and unfortunately I'm pretty late in the game. I wasn't
>> aware of that thread until yesterday.
>>
>> While the report is quite confusing, the reason seams pretty clear to me
>> as I've been thru quite some time-demanding debugging of a very similar
>> issue on Mac OS X. But I'm not totally sure whether we really hit the
>> same issue here, so I'd like to have your opinions first.
>>
>> The problem is appearantly the way the transfer buffer is allocated in
>> the drivers. In the snd-usb-caiaq driver, I used kzalloc() to get memory
>> which works fine on 32bit systems. On x86_64, however, it seems that
>> kzalloc() hands out memory beyond the 32bit addressable boundary, which
>> the DMA controller of the 32bit PCI-connected EHCI controller is unable
>> to write to or read from. Am I correct on this conclusion?
>
> That seems like the right answer. You are correct that an EHCI
> controller capable only of 32-bit memory accesses would not be able to
> use a buffer above the 4 GB line.
>
>> Depending on the condition of the memory management, things might work
>> or not, and especially right after a reboot, there's a better chance to
>> get lower memory.
>>
>> The fix is to use usb_buffer_alloc() for that purpose which ensures
>> memory that is suitable for DMA. And on x86_64, this also means that the
>> upper 32 bits of the address returned are all 0's.
>
> That is not a good fix. usb_buffer_alloc() provides coherent memory,
> which is not what we want. I believe the correct fix is to specify the
> GFP_DMA32 flag in the kzalloc() call.
>
> Of course, some EHCI hardware _is_ capable of using 64-bit addresses.
> But not all, and other controller types aren't. In principle we could
> create a new allocation routine, which would take a pointer to the USB
> bus as an additional argument and use it to decide whether the memory
> needs to lie below 4 GB. I'm not sure adding this extra complexity
> would be worthwhile.

AFAIK, the driver shouldn't have to worry about this at all. When the
buffer gets DMA-mapped for the controller, the DMA mapping code should
see that the device has a 32-bit DMA mask and either bounce or IOMMU-map
the memory so that it appears below 4GB.

Not to say that something might not be sabotaging this somehow, but this
complexity really shouldn't be needed.

>
>> If what I've stated is true, there are quite some more drivers affected
>> by this issue.
>
> Practically every USB driver, I should think. And maybe a lot of
> non-USB drivers too.
>
>> I collected a list of places where similar fixes are
>> needed, and I can send patches if I get a thumbs-up.
>>
>> Pedro is currently testing a patch I sent out yesterday.
>
> Good work -- it certainly would have taken me a long time to figure
> this out.
>
> Alan Stern
>

2010-04-07 23:59:31

by Robert Hancock

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 04/07/2010 01:13 PM, Alan Stern wrote:
> On Wed, 7 Apr 2010, Takashi Iwai wrote:
>
>>> Ok, I'll write some dummies for usb_malloc() and usb_zalloc() which
>>> will just call kmalloc() with GFP_DMA32 for now.
>>
>> Can't we provide only zalloc() variant? Zero'ing doesn't cost much,
>> and the buffer allocation shouldn't be called too often.
>
> Linus specifically requested us to avoid using kzalloc in usbfs. I
> can't find the message in the email archives, but Greg KH should be
> able to confirm it.
>
> As long as we're imitating kmalloc for one use, we might as well make
> it available to all.
>
>>> And while at it,
>>> usb_alloc_buffer() will be renamed to usb_alloc_consistent().
>>
>> Most of recent functions are named with "coherent".
>
> Yes, the terminology got a little confused between the PCI and DMA
> realms. I agree, "coherent" is better.
>
> BTW, although some EHCI controllers may support 64-bit DMA, the driver
> contains this:
>
> if (HCC_64BIT_ADDR(hcc_params)) {
> ehci_writel(ehci, 0,&ehci->regs->segment);
> #if 0
> // this is deeply broken on almost all architectures
> if (!dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)))
> ehci_info(ehci, "enabled 64bit DMA\n");
> #endif
> }
>
> I don't know if the comment is still true, but until the "#if 0" is
> removed, ehci-hcd won't make use of 64-bit DMA.

The comment is wrong (or at least outdated or based on an incorrect
assumption), but you're right, currently 64-bit DMA is not used on any
EHCI controllers. It could be, but it sounded like the consensus was it
wasn't worth the risk. Apparently Windows 7 started using it, and then
had to put out a patch because some NVidia EHCI controllers indicated
64-bit support but it didn't work properly. So you'd have to blacklist
those controllers, at least.

2010-04-08 00:35:36

by Greg KH

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 07, 2010 at 03:13:11PM -0400, Alan Stern wrote:
> On Wed, 7 Apr 2010, Takashi Iwai wrote:
>
> > > Ok, I'll write some dummies for usb_malloc() and usb_zalloc() which
> > > will just call kmalloc() with GFP_DMA32 for now.
> >
> > Can't we provide only zalloc() variant? Zero'ing doesn't cost much,
> > and the buffer allocation shouldn't be called too often.
>
> Linus specifically requested us to avoid using kzalloc in usbfs. I
> can't find the message in the email archives, but Greg KH should be
> able to confirm it.
>
> As long as we're imitating kmalloc for one use, we might as well make
> it available to all.
>
> > > And while at it,
> > > usb_alloc_buffer() will be renamed to usb_alloc_consistent().
> >
> > Most of recent functions are named with "coherent".
>
> Yes, the terminology got a little confused between the PCI and DMA
> realms. I agree, "coherent" is better.
>
> BTW, although some EHCI controllers may support 64-bit DMA, the driver
> contains this:
>
> if (HCC_64BIT_ADDR(hcc_params)) {
> ehci_writel(ehci, 0, &ehci->regs->segment);
> #if 0
> // this is deeply broken on almost all architectures
> if (!dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)))
> ehci_info(ehci, "enabled 64bit DMA\n");
> #endif
> }
>
> I don't know if the comment is still true, but until the "#if 0" is
> removed, ehci-hcd won't make use of 64-bit DMA.

I think someone tried to remove it recently, but I wouldn't let them :)

What a mess, hopefully xhci will just take over and save the world from
this whole thing...

thanks,

greg k-h

2010-04-08 02:10:23

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 7 Apr 2010, Robert Hancock wrote:

> >> The problem is appearantly the way the transfer buffer is allocated in
> >> the drivers. In the snd-usb-caiaq driver, I used kzalloc() to get memory
> >> which works fine on 32bit systems. On x86_64, however, it seems that
> >> kzalloc() hands out memory beyond the 32bit addressable boundary, which
> >> the DMA controller of the 32bit PCI-connected EHCI controller is unable
> >> to write to or read from. Am I correct on this conclusion?
> >
> > That seems like the right answer. You are correct that an EHCI
> > controller capable only of 32-bit memory accesses would not be able to
> > use a buffer above the 4 GB line.

> AFAIK, the driver shouldn't have to worry about this at all. When the
> buffer gets DMA-mapped for the controller, the DMA mapping code should
> see that the device has a 32-bit DMA mask and either bounce or IOMMU-map
> the memory so that it appears below 4GB.

That's true. It would of course be more efficient for the buffer to be
allocated below 4 GB, but it should work okay either way. Daniel, do
you have any idea why it fails?

Alan Stern

2010-04-08 07:30:48

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 07, 2010 at 10:10:17PM -0400, Alan Stern wrote:
> On Wed, 7 Apr 2010, Robert Hancock wrote:
>
> > >> The problem is appearantly the way the transfer buffer is allocated in
> > >> the drivers. In the snd-usb-caiaq driver, I used kzalloc() to get memory
> > >> which works fine on 32bit systems. On x86_64, however, it seems that
> > >> kzalloc() hands out memory beyond the 32bit addressable boundary, which
> > >> the DMA controller of the 32bit PCI-connected EHCI controller is unable
> > >> to write to or read from. Am I correct on this conclusion?
> > >
> > > That seems like the right answer. You are correct that an EHCI
> > > controller capable only of 32-bit memory accesses would not be able to
> > > use a buffer above the 4 GB line.
>
> > AFAIK, the driver shouldn't have to worry about this at all. When the
> > buffer gets DMA-mapped for the controller, the DMA mapping code should
> > see that the device has a 32-bit DMA mask and either bounce or IOMMU-map
> > the memory so that it appears below 4GB.
>
> That's true. It would of course be more efficient for the buffer to be
> allocated below 4 GB, but it should work okay either way. Daniel, do
> you have any idea why it fails?

No, and I can't do real tests as I lack a 64bit machine. I'll do some
more investigation later today, but for now the only explanation I have
is that not the remapped DMA buffer is used eventually by the EHCI code
but the physical address of the original buffer.

It would of course be best to fix the whole problem at this level, if
possible.

Daniel

2010-04-08 08:03:01

by Oliver Neukum

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

Am Mittwoch, 7. April 2010 17:35:51 schrieb Daniel Mack:
> > Alan, any objection to just using usb_buffer_alloc() for every driver?
> > Or is that too much overhead?
>
> FWIW, most drivers I've seen in the past hours use a wild mix of
> kmalloc(), kzalloc(), kcalloc() and usb_buffer_alloc(). That should
> really be unified.

kmalloc() & friends != usb_buffer_alloc(). They do different things.
It makes no sense to unify them. If you really need an ordinary
buffer DMA will surely work on, this needs a third primitive.

Regards
Oliver

2010-04-08 08:03:10

by Oliver Neukum

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

Am Mittwoch, 7. April 2010 17:46:17 schrieb Alan Stern:
> Or alternatively, instead of allocating regular memory the routine
> could simply fail. Then the caller would be responsible for checking
> and using regular memory instead of dma-consistent memory. Of course,
> that would put an even larger burden on the caller than just forcing it
> to keep track of what flag to use.

Then it would be sensible to pass it a filled URB, modify it or return
an error code.

Regards
Oliver

2010-04-08 11:07:51

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Thu, Apr 08, 2010 at 08:09:11AM +0200, Oliver Neukum wrote:
> Am Mittwoch, 7. April 2010 17:35:51 schrieb Daniel Mack:
> > > Alan, any objection to just using usb_buffer_alloc() for every driver?
> > > Or is that too much overhead?
> >
> > FWIW, most drivers I've seen in the past hours use a wild mix of
> > kmalloc(), kzalloc(), kcalloc() and usb_buffer_alloc(). That should
> > really be unified.
>
> kmalloc() & friends != usb_buffer_alloc(). They do different things.

I know. I just believe that many developers used usb_buffer_alloc() even
though they don't really need coherent DMA memory. The function's name
is misleading, and copy'n paste does the rest.

> It makes no sense to unify them. If you really need an ordinary
> buffer DMA will surely work on, this needs a third primitive.

I think it will help a lot to rename usb_buffer_alloc() in the first
place and then reconsider where coherent memory is really needed.

Daniel

2010-04-08 16:57:39

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Thu, 8 Apr 2010, Daniel Mack wrote:

> > > AFAIK, the driver shouldn't have to worry about this at all. When the
> > > buffer gets DMA-mapped for the controller, the DMA mapping code should
> > > see that the device has a 32-bit DMA mask and either bounce or IOMMU-map
> > > the memory so that it appears below 4GB.
> >
> > That's true. It would of course be more efficient for the buffer to be
> > allocated below 4 GB, but it should work okay either way. Daniel, do
> > you have any idea why it fails?
>
> No, and I can't do real tests as I lack a 64bit machine. I'll do some
> more investigation later today, but for now the only explanation I have
> is that not the remapped DMA buffer is used eventually by the EHCI code
> but the physical address of the original buffer.
>
> It would of course be best to fix the whole problem at this level, if
> possible.

It definitely needs to be fixed at this level. But I still think it's
appropriate to have new USB core functions for allocating and
deallocating I/O memory. The additional price is small compared to
constantly bouncing the buffers.

Pedro, in the hope of tracking down the problem, can you apply this
patch and see what output it produces in the system log when the
"interference" happens? (Warning: It will produce quite a lot of
output whenever you send data to the audio device -- between 500 and
1000 lines per second.)

Alan Stern



Index: 2.6.33/drivers/usb/core/hcd.c
===================================================================
--- 2.6.33.orig/drivers/usb/core/hcd.c
+++ 2.6.33/drivers/usb/core/hcd.c
@@ -1395,6 +1395,10 @@ int usb_hcd_submit_urb (struct urb *urb,
usbmon_urb_submit_error(&hcd->self, urb, status);
goto error;
}
+ if (usb_endpoint_is_isoc_out(&urb->ep->desc))
+ dev_info(&urb->dev->dev, "Iso xfer %p dma %llx\n",
+ urb->transfer_buffer,
+ (unsigned long long) urb->transfer_dma);

if (is_root_hub(urb->dev))
status = rh_urb_enqueue(hcd, urb);

2010-04-08 16:59:42

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Thu, 8 Apr 2010, Oliver Neukum wrote:

> Am Mittwoch, 7. April 2010 17:46:17 schrieb Alan Stern:
> > Or alternatively, instead of allocating regular memory the routine
> > could simply fail. Then the caller would be responsible for checking
> > and using regular memory instead of dma-consistent memory. Of course,
> > that would put an even larger burden on the caller than just forcing it
> > to keep track of what flag to use.
>
> Then it would be sensible to pass it a filled URB, modify it or return
> an error code.

That would work, but it doesn't match the way existing drivers use the
interface. For example, the audio driver allocates a 16-byte coherent
buffer and then uses four bytes from it for each of four different
URBs.

Alan Stern

2010-04-08 17:17:36

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 8 April 2010 17:57, Alan Stern <[email protected]> wrote:
> On Thu, 8 Apr 2010, Daniel Mack wrote:
>
>> > > AFAIK, the driver shouldn't have to worry about this at all. When the
>> > > buffer gets DMA-mapped for the controller, the DMA mapping code should
>> > > see that the device has a 32-bit DMA mask and either bounce or IOMMU-map
>> > > the memory so that it appears below 4GB.
>> >
>> > That's true. ?It would of course be more efficient for the buffer to be
>> > allocated below 4 GB, but it should work okay either way. ?Daniel, do
>> > you have any idea why it fails?
>>
>> No, and I can't do real tests as I lack a 64bit machine. I'll do some
>> more investigation later today, but for now the only explanation I have
>> is that not the remapped DMA buffer is used eventually by the EHCI code
>> but the physical address of the original buffer.
>>
>> It would of course be best to fix the whole problem at this level, if
>> possible.
>
> It definitely needs to be fixed at this level. ?But I still think it's
> appropriate to have new USB core functions for allocating and
> deallocating I/O memory. ?The additional price is small compared to
> constantly bouncing the buffers.
>
> Pedro, in the hope of tracking down the problem, can you apply this
> patch and see what output it produces in the system log when the
> "interference" happens? ?(Warning: It will produce quite a lot of
> output whenever you send data to the audio device -- between 500 and
> 1000 lines per second.)
>
> Alan Stern
>
>
>
> Index: 2.6.33/drivers/usb/core/hcd.c
> ===================================================================
> --- 2.6.33.orig/drivers/usb/core/hcd.c
> +++ 2.6.33/drivers/usb/core/hcd.c
> @@ -1395,6 +1395,10 @@ int usb_hcd_submit_urb (struct urb *urb,
> ? ? ? ? ? ? ? ?usbmon_urb_submit_error(&hcd->self, urb, status);
> ? ? ? ? ? ? ? ?goto error;
> ? ? ? ?}
> + ? ? ? if (usb_endpoint_is_isoc_out(&urb->ep->desc))
> + ? ? ? ? ? ? ? dev_info(&urb->dev->dev, "Iso xfer %p dma %llx\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? urb->transfer_buffer,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (unsigned long long) urb->transfer_dma);
>
> ? ? ? ?if (is_root_hub(urb->dev))
> ? ? ? ? ? ? ? ?status = rh_urb_enqueue(hcd, urb);
>
>

I'll do it tonight and send you the results tomorrow morning. Do you
want CONFIG_USB_DEBUG enabled or disabled?

Pedro

2010-04-08 18:18:11

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Thu, 8 Apr 2010, Pedro Ribeiro wrote:

> > Pedro, in the hope of tracking down the problem, can you apply this
> > patch and see what output it produces in the system log when the
> > "interference" happens? ?(Warning: It will produce quite a lot of
> > output whenever you send data to the audio device -- between 500 and
> > 1000 lines per second.)

> I'll do it tonight and send you the results tomorrow morning. Do you
> want CONFIG_USB_DEBUG enabled or disabled?

It doesn't matter.

Alan Stern

2010-04-08 21:24:38

by Oliver Neukum

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

Am Donnerstag, 8. April 2010 18:59:38 schrieb Alan Stern:
> On Thu, 8 Apr 2010, Oliver Neukum wrote:
>
> > Am Mittwoch, 7. April 2010 17:46:17 schrieb Alan Stern:
> > > Or alternatively, instead of allocating regular memory the routine
> > > could simply fail. Then the caller would be responsible for checking
> > > and using regular memory instead of dma-consistent memory. Of course,
> > > that would put an even larger burden on the caller than just forcing it
> > > to keep track of what flag to use.
> >
> > Then it would be sensible to pass it a filled URB, modify it or return
> > an error code.
>
> That would work, but it doesn't match the way existing drivers use the
> interface. For example, the audio driver allocates a 16-byte coherent
> buffer and then uses four bytes from it for each of four different
> URBs.

That will not work with any fallback that does not yield a coherent buffer.

Regards
Oliver

2010-04-08 22:20:39

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Thu, 8 Apr 2010, Oliver Neukum wrote:

> Am Donnerstag, 8. April 2010 18:59:38 schrieb Alan Stern:
> > On Thu, 8 Apr 2010, Oliver Neukum wrote:
> >
> > > Am Mittwoch, 7. April 2010 17:46:17 schrieb Alan Stern:
> > > > Or alternatively, instead of allocating regular memory the routine
> > > > could simply fail. Then the caller would be responsible for checking
> > > > and using regular memory instead of dma-consistent memory. Of course,
> > > > that would put an even larger burden on the caller than just forcing it
> > > > to keep track of what flag to use.
> > >
> > > Then it would be sensible to pass it a filled URB, modify it or return
> > > an error code.
> >
> > That would work, but it doesn't match the way existing drivers use the
> > interface. For example, the audio driver allocates a 16-byte coherent
> > buffer and then uses four bytes from it for each of four different
> > URBs.
>
> That will not work with any fallback that does not yield a coherent buffer.

What you mean isn't entirely clear. But it certainly does work in
various circumstances that don't yield coherent buffers. For example,
it works if the controller uses PIO instead of DMA. It also works if
the controller uses DMA and the URBs have to be bounced.

Alan Stern

2010-04-08 23:13:14

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 8 April 2010 17:57, Alan Stern <[email protected]> wrote:
> On Thu, 8 Apr 2010, Daniel Mack wrote:
>
>> > > AFAIK, the driver shouldn't have to worry about this at all. When the
>> > > buffer gets DMA-mapped for the controller, the DMA mapping code should
>> > > see that the device has a 32-bit DMA mask and either bounce or IOMMU-map
>> > > the memory so that it appears below 4GB.
>> >
>> > That's true. ?It would of course be more efficient for the buffer to be
>> > allocated below 4 GB, but it should work okay either way. ?Daniel, do
>> > you have any idea why it fails?
>>
>> No, and I can't do real tests as I lack a 64bit machine. I'll do some
>> more investigation later today, but for now the only explanation I have
>> is that not the remapped DMA buffer is used eventually by the EHCI code
>> but the physical address of the original buffer.
>>
>> It would of course be best to fix the whole problem at this level, if
>> possible.
>
> It definitely needs to be fixed at this level. ?But I still think it's
> appropriate to have new USB core functions for allocating and
> deallocating I/O memory. ?The additional price is small compared to
> constantly bouncing the buffers.
>
> Pedro, in the hope of tracking down the problem, can you apply this
> patch and see what output it produces in the system log when the
> "interference" happens? ?(Warning: It will produce quite a lot of
> output whenever you send data to the audio device -- between 500 and
> 1000 lines per second.)
>
> Alan Stern
>
>
>
> Index: 2.6.33/drivers/usb/core/hcd.c
> ===================================================================
> --- 2.6.33.orig/drivers/usb/core/hcd.c
> +++ 2.6.33/drivers/usb/core/hcd.c
> @@ -1395,6 +1395,10 @@ int usb_hcd_submit_urb (struct urb *urb,
> ? ? ? ? ? ? ? ?usbmon_urb_submit_error(&hcd->self, urb, status);
> ? ? ? ? ? ? ? ?goto error;
> ? ? ? ?}
> + ? ? ? if (usb_endpoint_is_isoc_out(&urb->ep->desc))
> + ? ? ? ? ? ? ? dev_info(&urb->dev->dev, "Iso xfer %p dma %llx\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? urb->transfer_buffer,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (unsigned long long) urb->transfer_dma);
>
> ? ? ? ?if (is_root_hub(urb->dev))
> ? ? ? ? ? ? ? ?status = rh_urb_enqueue(hcd, urb);
>
>

Hi Alan,

here is the output of the patch you sent me when the interference is triggered.

The log is long, 1.3mb in size.

Please let me know if you need anything more.

Regards,
Pedro


Attachments:
iso.xfer.tar.bz2 (78.55 kB)

2010-04-09 00:01:34

by Robert Hancock

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 04/07/2010 06:33 PM, Greg KH wrote:
> On Wed, Apr 07, 2010 at 03:13:11PM -0400, Alan Stern wrote:
>> On Wed, 7 Apr 2010, Takashi Iwai wrote:
>>
>>>> Ok, I'll write some dummies for usb_malloc() and usb_zalloc() which
>>>> will just call kmalloc() with GFP_DMA32 for now.
>>>
>>> Can't we provide only zalloc() variant? Zero'ing doesn't cost much,
>>> and the buffer allocation shouldn't be called too often.
>>
>> Linus specifically requested us to avoid using kzalloc in usbfs. I
>> can't find the message in the email archives, but Greg KH should be
>> able to confirm it.
>>
>> As long as we're imitating kmalloc for one use, we might as well make
>> it available to all.
>>
>>>> And while at it,
>>>> usb_alloc_buffer() will be renamed to usb_alloc_consistent().
>>>
>>> Most of recent functions are named with "coherent".
>>
>> Yes, the terminology got a little confused between the PCI and DMA
>> realms. I agree, "coherent" is better.
>>
>> BTW, although some EHCI controllers may support 64-bit DMA, the driver
>> contains this:
>>
>> if (HCC_64BIT_ADDR(hcc_params)) {
>> ehci_writel(ehci, 0,&ehci->regs->segment);
>> #if 0
>> // this is deeply broken on almost all architectures
>> if (!dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)))
>> ehci_info(ehci, "enabled 64bit DMA\n");
>> #endif
>> }
>>
>> I don't know if the comment is still true, but until the "#if 0" is
>> removed, ehci-hcd won't make use of 64-bit DMA.
>
> I think someone tried to remove it recently, but I wouldn't let them :)
>
> What a mess, hopefully xhci will just take over and save the world from
> this whole thing...

True.. except for the fact that the xhci driver currently doesn't do
64-bit DMA either, nor does it support MSI even though the HW supports
it (surprisingly enough the NEC Windows driver does, MSI-X even). At
this point only Intel likely knows how to do this properly, though,
since AFAICS the spec isn't publicly available yet.

2010-04-09 06:05:17

by Oliver Neukum

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

Am Freitag, 9. April 2010 00:20:36 schrieb Alan Stern:
> > > That would work, but it doesn't match the way existing drivers use the
> > > interface. For example, the audio driver allocates a 16-byte coherent
> > > buffer and then uses four bytes from it for each of four different
> > > URBs.
> >
> > That will not work with any fallback that does not yield a coherent buffer.
>
> What you mean isn't entirely clear. But it certainly does work in
> various circumstances that don't yield coherent buffers. For example,
> it works if the controller uses PIO instead of DMA. It also works if
> the controller uses DMA and the URBs have to be bounced.

It'll work on x86. On incoherent architectures this violates the cacheline
rules for DMA-mapping if you have to bounce. So it seems to me that
if you want to share a buffer between URBs, it must be coherent.

Regards
Oliver

2010-04-09 14:42:01

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Fri, 9 Apr 2010, Oliver Neukum wrote:

> Am Freitag, 9. April 2010 00:20:36 schrieb Alan Stern:
> > > > That would work, but it doesn't match the way existing drivers use the
> > > > interface. For example, the audio driver allocates a 16-byte coherent
> > > > buffer and then uses four bytes from it for each of four different
> > > > URBs.
> > >
> > > That will not work with any fallback that does not yield a coherent buffer.
> >
> > What you mean isn't entirely clear. But it certainly does work in
> > various circumstances that don't yield coherent buffers. For example,
> > it works if the controller uses PIO instead of DMA. It also works if
> > the controller uses DMA and the URBs have to be bounced.
>
> It'll work on x86. On incoherent architectures this violates the cacheline
> rules for DMA-mapping if you have to bounce.

Not true. Consider: The driver allocates a 16-byte buffer (xbuf)
divided up into four sets of four bytes, and sets

urb[i].transfer_buffer_dma = xbuf_dma + 4*i;

Then usb_submit_urb(urb[i]) will copy the appropriate four bytes to a
bounce buffer and map the bounce buffer. Accesses to the other parts
of xbuf won't violate the cacheline rules, because xbuf isn't mapped
for DMA -- only the bounce buffer is. When urb[i] completes, the
bounce buffer contents will be copied back to the original four bytes
in xbuf. Again, there is no violation of cacheline rules.

> So it seems to me that
> if you want to share a buffer between URBs, it must be coherent.

No. But it must be allocated via usb_alloc_buffer() (or whatever that
routine gets renamed to).

Alan Stern

2010-04-09 14:50:32

by Oliver Neukum

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

Am Freitag, 9. April 2010 16:41:48 schrieb Alan Stern:
> > It'll work on x86. On incoherent architectures this violates the cacheline
> > rules for DMA-mapping if you have to bounce.
>
> Not true. Consider: The driver allocates a 16-byte buffer (xbuf)
> divided up into four sets of four bytes, and sets
>
> urb[i].transfer_buffer_dma = xbuf_dma + 4*i;
>
> Then usb_submit_urb(urb[i]) will copy the appropriate four bytes to a
> bounce buffer and map the bounce buffer. Accesses to the other parts
> of xbuf won't violate the cacheline rules, because xbuf isn't mapped
> for DMA -- only the bounce buffer is. When urb[i] completes, the
> bounce buffer contents will be copied back to the original four bytes
> in xbuf. Again, there is no violation of cacheline rules.

I think you are assuming that either every or no part of the buffer is mapped
for DMA in place. I don't think you can assume that.

Regards
Oliver

2010-04-09 15:15:46

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Fri, 9 Apr 2010, Oliver Neukum wrote:

> Am Freitag, 9. April 2010 16:41:48 schrieb Alan Stern:
> > > It'll work on x86. On incoherent architectures this violates the cacheline
> > > rules for DMA-mapping if you have to bounce.
> >
> > Not true. Consider: The driver allocates a 16-byte buffer (xbuf)
> > divided up into four sets of four bytes, and sets
> >
> > urb[i].transfer_buffer_dma = xbuf_dma + 4*i;
> >
> > Then usb_submit_urb(urb[i]) will copy the appropriate four bytes to a
> > bounce buffer and map the bounce buffer. Accesses to the other parts
> > of xbuf won't violate the cacheline rules, because xbuf isn't mapped
> > for DMA -- only the bounce buffer is. When urb[i] completes, the
> > bounce buffer contents will be copied back to the original four bytes
> > in xbuf. Again, there is no violation of cacheline rules.
>
> I think you are assuming that either every or no part of the buffer is mapped
> for DMA in place. I don't think you can assume that.

Yes I can, because the code that makes this decision is part of
usbcore and it is under my control.

Alan Stern

2010-04-09 16:01:30

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Fri, 9 Apr 2010, Pedro Ribeiro wrote:

> On 8 April 2010 17:57, Alan Stern <[email protected]> wrote:
> > On Thu, 8 Apr 2010, Daniel Mack wrote:
> >
> >> > > AFAIK, the driver shouldn't have to worry about this at all. When the
> >> > > buffer gets DMA-mapped for the controller, the DMA mapping code should
> >> > > see that the device has a 32-bit DMA mask and either bounce or IOMMU-map
> >> > > the memory so that it appears below 4GB.
> >> >
> >> > That's true. ?It would of course be more efficient for the buffer to be
> >> > allocated below 4 GB, but it should work okay either way. ?Daniel, do
> >> > you have any idea why it fails?
> >>
> >> No, and I can't do real tests as I lack a 64bit machine. I'll do some
> >> more investigation later today, but for now the only explanation I have
> >> is that not the remapped DMA buffer is used eventually by the EHCI code
> >> but the physical address of the original buffer.
> >>
> >> It would of course be best to fix the whole problem at this level, if
> >> possible.
> >
> > It definitely needs to be fixed at this level. ?But I still think it's
> > appropriate to have new USB core functions for allocating and
> > deallocating I/O memory. ?The additional price is small compared to
> > constantly bouncing the buffers.
> >
> > Pedro, in the hope of tracking down the problem, can you apply this
> > patch and see what output it produces in the system log when the
> > "interference" happens? ?(Warning: It will produce quite a lot of
> > output whenever you send data to the audio device -- between 500 and
> > 1000 lines per second.)

> Hi Alan,
>
> here is the output of the patch you sent me when the interference is triggered.
>
> The log is long, 1.3mb in size.

I don't see anything suspicious. The transfer_buffer addresses repeat
every 32 URBs, and the DMA addresses cycle almost entirely uniformly
from 0x20000000 to 0x23ffffff in units of 0x2000 (there are a few gaps
where the interval is a little bigger).

Alan Stern

2010-04-09 16:50:21

by Sarah Sharp

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Thu, Apr 08, 2010 at 06:01:27PM -0600, Robert Hancock wrote:
> On 04/07/2010 06:33 PM, Greg KH wrote:
> >On Wed, Apr 07, 2010 at 03:13:11PM -0400, Alan Stern wrote:
> >>On Wed, 7 Apr 2010, Takashi Iwai wrote:
> >>
> >>>>Ok, I'll write some dummies for usb_malloc() and usb_zalloc() which
> >>>>will just call kmalloc() with GFP_DMA32 for now.
> >>>
> >>>Can't we provide only zalloc() variant? Zero'ing doesn't cost much,
> >>>and the buffer allocation shouldn't be called too often.
> >>
> >>Linus specifically requested us to avoid using kzalloc in usbfs. I
> >>can't find the message in the email archives, but Greg KH should be
> >>able to confirm it.
> >>
> >>As long as we're imitating kmalloc for one use, we might as well make
> >>it available to all.
> >>
> >>>>And while at it,
> >>>>usb_alloc_buffer() will be renamed to usb_alloc_consistent().
> >>>
> >>>Most of recent functions are named with "coherent".
> >>
> >>Yes, the terminology got a little confused between the PCI and DMA
> >>realms. I agree, "coherent" is better.
> >>
> >>BTW, although some EHCI controllers may support 64-bit DMA, the driver
> >>contains this:
> >>
> >> if (HCC_64BIT_ADDR(hcc_params)) {
> >> ehci_writel(ehci, 0,&ehci->regs->segment);
> >>#if 0
> >>// this is deeply broken on almost all architectures
> >> if (!dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)))
> >> ehci_info(ehci, "enabled 64bit DMA\n");
> >>#endif
> >> }
> >>
> >>I don't know if the comment is still true, but until the "#if 0" is
> >>removed, ehci-hcd won't make use of 64-bit DMA.
> >
> >I think someone tried to remove it recently, but I wouldn't let them :)
> >
> >What a mess, hopefully xhci will just take over and save the world from
> >this whole thing...

I hate to break it to you, but 64-bit DMA support is optional for an
xHCI implementation. There's a bit in HCCPARAMS that tells whether the
host supports it (see the HCC_64BIT_ADDR macro in xhci.h). The xHCI
driver currently doesn't do anything with that bit, although it should.
All the implementations I've seen do 64-bit DMA.

> True.. except for the fact that the xhci driver currently doesn't do
> 64-bit DMA either

What makes you think that? I've seen URB buffers with 64-bit DMA
addresses. I can tell when the debug polling loop runs and I look at
the DMA addresses the xHCI driver is feeding to the hardware:

Dev 1 endpoint ring 0:
xhci_hcd 0000:05:00.0: @71a49800 01000680 00080000 00000008 00000841

So the TRB at address 71a49800 is pointing to a buffer at address
0x0008000001000680.

If I'm setting a DMA mask wrong somewhere, or doing something else to
limit the DMA to 32-bit, then please let me know.

> nor does it support MSI even though the HW
> supports it (surprisingly enough the NEC Windows driver does, MSI-X
> even).

There's a patch from AMD to enable MSI-X. The code was there, just
commented out because the early prototypes didn't do MSI-X.

> At this point only Intel likely knows how to do this
> properly, though, since AFAICS the spec isn't publicly available
> yet.

I have tried very hard to fix this, and will continue to do so.

Sarah Sharp

2010-04-09 18:09:51

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Fri, Apr 09, 2010 at 12:01:27PM -0400, Alan Stern wrote:
> On Fri, 9 Apr 2010, Pedro Ribeiro wrote:
> > here is the output of the patch you sent me when the interference is triggered.
> >
> > The log is long, 1.3mb in size.
>
> I don't see anything suspicious. The transfer_buffer addresses repeat
> every 32 URBs, and the DMA addresses cycle almost entirely uniformly
> from 0x20000000 to 0x23ffffff in units of 0x2000 (there are a few gaps
> where the interval is a little bigger).

The DMA pointers do indeed look sane. I wanted to take a deeper look at
this and set up a 64bit system today. However, I fail to see the problem
here. Pedro, how much RAM does your machine have installed?

Daniel

2010-04-09 18:19:28

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 9 April 2010 19:09, Daniel Mack <[email protected]> wrote:
> On Fri, Apr 09, 2010 at 12:01:27PM -0400, Alan Stern wrote:
>> On Fri, 9 Apr 2010, Pedro Ribeiro wrote:
>> > here is the output of the patch you sent me when the interference is triggered.
>> >
>> > The log is long, 1.3mb in size.
>>
>> I don't see anything suspicious. ?The transfer_buffer addresses repeat
>> every 32 URBs, and the DMA addresses cycle almost entirely uniformly
>> from 0x20000000 to 0x23ffffff in units of 0x2000 (there are a few gaps
>> where the interval is a little bigger).
>
> The DMA pointers do indeed look sane. I wanted to take a deeper look at
> this and set up a 64bit system today. However, I fail to see the problem
> here. Pedro, how much RAM does your machine have installed?
>
> Daniel
>
>

It has 4 GB.

Pedro

2010-04-09 19:34:12

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Fri, 9 Apr 2010, Pedro Ribeiro wrote:

> > The DMA pointers do indeed look sane. I wanted to take a deeper look at
> > this and set up a 64bit system today. However, I fail to see the problem
> > here. Pedro, how much RAM does your machine have installed?

> It has 4 GB.

That means DMA mapping cannot be the cause of the problem. :-(

Alan Stern

2010-04-09 20:15:31

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Fri, Apr 09, 2010 at 03:34:06PM -0400, Alan Stern wrote:
> On Fri, 9 Apr 2010, Pedro Ribeiro wrote:
>
> > > The DMA pointers do indeed look sane. I wanted to take a deeper look at
> > > this and set up a 64bit system today. However, I fail to see the problem
> > > here. Pedro, how much RAM does your machine have installed?
>
> > It has 4 GB.
>
> That means DMA mapping cannot be the cause of the problem. :-(

FWIW, as I stated in the first message of this thread, I had very
similar bug reports for a Mac OS X driver I'm maintaining, and the
solution that fixed everything was to force memory that has a _physical_
buffer address mask of 0x00000000ffffffff. And all machines I've seen
the bug on had 4GB of RAM or less. So appearantly, without that force
option, memory beyond the 4GB range was provided.

But I can't tell whether this effect also counts for Linux, and I must
admit I lack a deep enough understanding about the kernel's memory
management in 64bit mode and about how the DMA bouncing and remapping
logic works. Does anyone have an idea about how to explain that?

Daniel

2010-04-09 20:28:16

by Konrad Rzeszutek Wilk

[permalink] [raw]
Subject: Re: [LKML] Re: USB transfer_buffer allocations on 64bit systems

On Fri, Apr 09, 2010 at 03:34:06PM -0400, Alan Stern wrote:
> On Fri, 9 Apr 2010, Pedro Ribeiro wrote:
>
> > > The DMA pointers do indeed look sane. I wanted to take a deeper look at
> > > this and set up a 64bit system today. However, I fail to see the problem
> > > here. Pedro, how much RAM does your machine have installed?
>
> > It has 4 GB.
>
> That means DMA mapping cannot be the cause of the problem. :-(

That isn't entirely true. The BIOS usually allocates a 256 MB ACPI/PCI hole
that is under the 4GB.

So end up with 3.7 GB, then the 256MB hole, and then right above the 4GB
you the the remaining memory: 4.3GB.

2010-04-09 20:51:54

by Oliver Neukum

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

Am Freitag, 9. April 2010 17:15:43 schrieb Alan Stern:
> > > Then usb_submit_urb(urb[i]) will copy the appropriate four bytes to a
> > > bounce buffer and map the bounce buffer. Accesses to the other parts
> > > of xbuf won't violate the cacheline rules, because xbuf isn't mapped
> > > for DMA -- only the bounce buffer is. When urb[i] completes, the
> > > bounce buffer contents will be copied back to the original four bytes
> > > in xbuf. Again, there is no violation of cacheline rules.
> >
> > I think you are assuming that either every or no part of the buffer is mapped
> > for DMA in place. I don't think you can assume that.
>
> Yes I can, because the code that makes this decision is part of
> usbcore and it is under m

It seems to me that in usbcore you can positively know that a buffer
will be mapped. However if the mapping is not done in usbcore you
cannot know what the HCD driver will do to a buffer, in particular
you don't know whether it will be processed by PIO or mapped for
DMA.

Maybe I understand this wrongly. Which code exactly were you refering to?

Regards
Oliver

2010-04-09 21:21:14

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Fri, 9 Apr 2010, Oliver Neukum wrote:

> Am Freitag, 9. April 2010 17:15:43 schrieb Alan Stern:
> > > > Then usb_submit_urb(urb[i]) will copy the appropriate four bytes to a
> > > > bounce buffer and map the bounce buffer. Accesses to the other parts
> > > > of xbuf won't violate the cacheline rules, because xbuf isn't mapped
> > > > for DMA -- only the bounce buffer is. When urb[i] completes, the
> > > > bounce buffer contents will be copied back to the original four bytes
> > > > in xbuf. Again, there is no violation of cacheline rules.
> > >
> > > I think you are assuming that either every or no part of the buffer is mapped
> > > for DMA in place. I don't think you can assume that.
> >
> > Yes I can, because the code that makes this decision is part of
> > usbcore and it is under m
>
> It seems to me that in usbcore you can positively know that a buffer
> will be mapped. However if the mapping is not done in usbcore you
> cannot know what the HCD driver will do to a buffer, in particular
> you don't know whether it will be processed by PIO or mapped for
> DMA.

The mapping is always done either by usb_buffer_alloc() or by
map_urb_for_dma(). Both functions are in usbcore.

> Maybe I understand this wrongly. Which code exactly were you refering to?

Search for usages of "syncbuf" and "sync_dma" in sound/usb/usbaudio.c.

Alan Stern

2010-04-09 21:23:29

by Alan Stern

[permalink] [raw]
Subject: Re: [LKML] Re: USB transfer_buffer allocations on 64bit systems

On Fri, 9 Apr 2010, Konrad Rzeszutek Wilk wrote:

> On Fri, Apr 09, 2010 at 03:34:06PM -0400, Alan Stern wrote:
> > On Fri, 9 Apr 2010, Pedro Ribeiro wrote:
> >
> > > > The DMA pointers do indeed look sane. I wanted to take a deeper look at
> > > > this and set up a 64bit system today. However, I fail to see the problem
> > > > here. Pedro, how much RAM does your machine have installed?
> >
> > > It has 4 GB.
> >
> > That means DMA mapping cannot be the cause of the problem. :-(
>
> That isn't entirely true. The BIOS usually allocates a 256 MB ACPI/PCI hole
> that is under the 4GB.
>
> So end up with 3.7 GB, then the 256MB hole, and then right above the 4GB
> you the the remaining memory: 4.3GB.

How can Pedro find out what physical addresses are in use on his
system?

Alan Stern

2010-04-09 22:11:59

by Robert Hancock

[permalink] [raw]
Subject: Re: [LKML] Re: USB transfer_buffer allocations on 64bit systems

On Fri, Apr 9, 2010 at 3:23 PM, Alan Stern <[email protected]> wrote:
> On Fri, 9 Apr 2010, Konrad Rzeszutek Wilk wrote:
>
>> On Fri, Apr 09, 2010 at 03:34:06PM -0400, Alan Stern wrote:
>> > On Fri, 9 Apr 2010, Pedro Ribeiro wrote:
>> >
>> > > > The DMA pointers do indeed look sane. I wanted to take a deeper look at
>> > > > this and set up a 64bit system today. However, I fail to see the problem
>> > > > here. Pedro, how much RAM does your machine have installed?
>> >
>> > > It has 4 GB.
>> >
>> > That means DMA mapping cannot be the cause of the problem. ?:-(
>>
>> That isn't entirely true. The BIOS usually allocates a 256 MB ACPI/PCI hole
>> that is under the 4GB.
>>
>> So end up with 3.7 GB, then the 256MB hole, and then right above the 4GB
>> you the the remaining memory: 4.3GB.
>
> How can Pedro find out what physical addresses are in use on his
> system?

If you have 4GB of RAM then almost certainly you have memory located
at addresses over 4GB. If you look at the e820 memory map printed at
the start of dmesg on bootup and see entries with addresses of
100000000 or higher reported as usable, then this is the case.

2010-04-09 23:38:16

by Robert Hancock

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Fri, Apr 9, 2010 at 10:50 AM, Sarah Sharp
<[email protected]> wrote:
>> >>I don't know if the comment is still true, but until the "#if 0" is
>> >>removed, ehci-hcd won't make use of 64-bit DMA.
>> >
>> >I think someone tried to remove it recently, but I wouldn't let them :)
>> >
>> >What a mess, hopefully xhci will just take over and save the world from
>> >this whole thing...
>
> I hate to break it to you, but 64-bit DMA support is optional for an
> xHCI implementation. ?There's a bit in HCCPARAMS that tells whether the
> host supports it (see the HCC_64BIT_ADDR macro in xhci.h). ?The xHCI
> driver currently doesn't do anything with that bit, although it should.
> All the implementations I've seen do 64-bit DMA.
>
>> True.. except for the fact that the xhci driver currently doesn't do
>> 64-bit DMA either
>
> What makes you think that? ?I've seen URB buffers with 64-bit DMA
> addresses. ?I can tell when the debug polling loop runs and I look at
> the DMA addresses the xHCI driver is feeding to the hardware:
>
> Dev 1 endpoint ring 0:
> xhci_hcd 0000:05:00.0: @71a49800 01000680 00080000 00000008 00000841
>
> So the TRB at address 71a49800 is pointing to a buffer at address
> 0x0008000001000680.

I'm not sure why the address would be that huge, unless it's not
actually a physical address, or there's some kind of remapping going
on?

>
> If I'm setting a DMA mask wrong somewhere, or doing something else to
> limit the DMA to 32-bit, then please let me know.

The DMA mask for the controller isn't being set anywhere (in the
version that's in Linus' current git anyway). In that case it'll
default to 32-bit and any DMA mappings above 4GB will need to be
remapped. The controller driver doesn't do the mapping itself but the
USB core does, passing in the controller device as the one doing the
DMA, so if the controller's DMA mask is set to 32-bit then the buffers
passed in will get remapped/bounced accordingly.

You should likely be setting the DMA mask for the controller device to
64-bit if the HCC_64BIT_ADDR flag is set, similar to the code in
ehci-hcd.c which is currently #if 0'ed out.

You can see the currently set mask in sysfs under
/sys/devices/pci(whatever)/dma_mask_bits.

>
>> nor does it support MSI even though the HW
>> supports it (surprisingly enough the NEC Windows driver does, MSI-X
>> even).
>
> There's a patch from AMD to enable MSI-X. ?The code was there, just
> commented out because the early prototypes didn't do MSI-X.

Ah, I see it. That could presumably be tested now (the NEC D720200F1
chip on the Asus U3S6 card I have seems to support MSI-X with 8
vectors).

>
>> At this point only Intel likely knows how to do this
>> properly, though, since AFAICS the spec isn't publicly available
>> yet.
>
> I have tried very hard to fix this, and will continue to do so.
>
> Sarah Sharp
>

2010-04-10 08:35:03

by Daniel Mack

[permalink] [raw]
Subject: Re: [alsa-devel] USB transfer_buffer allocations on 64bit systems

On Fri, Apr 09, 2010 at 05:38:13PM -0600, Robert Hancock wrote:
> On Fri, Apr 9, 2010 at 10:50 AM, Sarah Sharp
> <[email protected]> wrote:
> > What makes you think that? ?I've seen URB buffers with 64-bit DMA
> > addresses. ?I can tell when the debug polling loop runs and I look at
> > the DMA addresses the xHCI driver is feeding to the hardware:
> >
> > Dev 1 endpoint ring 0:
> > xhci_hcd 0000:05:00.0: @71a49800 01000680 00080000 00000008 00000841
> >
> > So the TRB at address 71a49800 is pointing to a buffer at address
> > 0x0008000001000680.
>
> I'm not sure why the address would be that huge, unless it's not
> actually a physical address, or there's some kind of remapping going
> on?
>
> >
> > If I'm setting a DMA mask wrong somewhere, or doing something else to
> > limit the DMA to 32-bit, then please let me know.
>
> The DMA mask for the controller isn't being set anywhere (in the
> version that's in Linus' current git anyway). In that case it'll
> default to 32-bit and any DMA mappings above 4GB will need to be
> remapped. The controller driver doesn't do the mapping itself but the
> USB core does, passing in the controller device as the one doing the
> DMA, so if the controller's DMA mask is set to 32-bit then the buffers
> passed in will get remapped/bounced accordingly.

So if we're seeing physical addresses in the log above, and the xHCI
driver does not explicitly allow the USB core to use addresses above
4GB, why shouldn't the same thing be true as well for EHCI?
(Which would then be exactly the case we're seeing)

Daniel

2010-04-10 12:49:18

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Fri, Apr 09, 2010 at 07:19:22PM +0100, Pedro Ribeiro wrote:
> On 9 April 2010 19:09, Daniel Mack <[email protected]> wrote:
> > On Fri, Apr 09, 2010 at 12:01:27PM -0400, Alan Stern wrote:
> >> I don't see anything suspicious. ?The transfer_buffer addresses repeat
> >> every 32 URBs, and the DMA addresses cycle almost entirely uniformly
> >> from 0x20000000 to 0x23ffffff in units of 0x2000 (there are a few gaps
> >> where the interval is a little bigger).
> >
> > The DMA pointers do indeed look sane. I wanted to take a deeper look at
> > this and set up a 64bit system today. However, I fail to see the problem
> > here. Pedro, how much RAM does your machine have installed?
> >
> > Daniel
> >
> >
>
> It has 4 GB.

Upgraded my machine now to 4GB, but I still can't reproduce this bug.
Pedro, can you send your config, please?

Daniel

2010-04-10 13:21:25

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 10 April 2010 13:49, Daniel Mack <[email protected]> wrote:
> On Fri, Apr 09, 2010 at 07:19:22PM +0100, Pedro Ribeiro wrote:
>> On 9 April 2010 19:09, Daniel Mack <[email protected]> wrote:
>> > On Fri, Apr 09, 2010 at 12:01:27PM -0400, Alan Stern wrote:
>> >> I don't see anything suspicious. ?The transfer_buffer addresses repeat
>> >> every 32 URBs, and the DMA addresses cycle almost entirely uniformly
>> >> from 0x20000000 to 0x23ffffff in units of 0x2000 (there are a few gaps
>> >> where the interval is a little bigger).
>> >
>> > The DMA pointers do indeed look sane. I wanted to take a deeper look at
>> > this and set up a 64bit system today. However, I fail to see the problem
>> > here. Pedro, how much RAM does your machine have installed?
>> >
>> > Daniel
>> >
>> >
>>
>> It has 4 GB.
>
> Upgraded my machine now to 4GB, but I still can't reproduce this bug.
> Pedro, can you send your config, please?
>
> Daniel
>

Here it is. It is configured for realtime and TuxOnIce patches.
However, the bug still occurs without these kernel patches.

Pedro


Attachments:
.config_2.6.33-rt-ToI (88.69 kB)

2010-04-10 17:02:56

by Robert Hancock

[permalink] [raw]
Subject: Re: [alsa-devel] USB transfer_buffer allocations on 64bit systems

On Sat, Apr 10, 2010 at 2:34 AM, Daniel Mack <[email protected]> wrote:
> On Fri, Apr 09, 2010 at 05:38:13PM -0600, Robert Hancock wrote:
>> On Fri, Apr 9, 2010 at 10:50 AM, Sarah Sharp
>> <[email protected]> wrote:
>> > What makes you think that? ?I've seen URB buffers with 64-bit DMA
>> > addresses. ?I can tell when the debug polling loop runs and I look at
>> > the DMA addresses the xHCI driver is feeding to the hardware:
>> >
>> > Dev 1 endpoint ring 0:
>> > xhci_hcd 0000:05:00.0: @71a49800 01000680 00080000 00000008 00000841
>> >
>> > So the TRB at address 71a49800 is pointing to a buffer at address
>> > 0x0008000001000680.
>>
>> I'm not sure why the address would be that huge, unless it's not
>> actually a physical address, or there's some kind of remapping going
>> on?
>>
>> >
>> > If I'm setting a DMA mask wrong somewhere, or doing something else to
>> > limit the DMA to 32-bit, then please let me know.
>>
>> The DMA mask for the controller isn't being set anywhere (in the
>> version that's in Linus' current git anyway). In that case it'll
>> default to 32-bit and any DMA mappings above 4GB will need to be
>> remapped. The controller driver doesn't do the mapping itself but the
>> USB core does, passing in the controller device as the one doing the
>> DMA, so if the controller's DMA mask is set to 32-bit then the buffers
>> passed in will get remapped/bounced accordingly.
>
> So if we're seeing physical addresses in the log above, and the xHCI
> driver does not explicitly allow the USB core to use addresses above
> 4GB, why shouldn't the same thing be true as well for EHCI?
> (Which would then be exactly the case we're seeing)

That is a bit suspicious, yes. With the DMA mask at default I don't
expect that should happen. Sarah, what kind of traffic was happening
when you saw that (bulk, isochronous, etc)?

If this apparent EHCI problem is reproducible, it might be useful to
add some code that warns if anything non-zero gets written to the
hw_bufp_hi and hw_buf_hi members in the descriptors.

Also, booting with mem=4096M on an affected system would also tell you
if it's related to using memory above 4GB.

2010-04-12 09:00:01

by Andi Kleen

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

Alan Stern <[email protected]> writes:
>>
>> The fix is to use usb_buffer_alloc() for that purpose which ensures
>> memory that is suitable for DMA. And on x86_64, this also means that the
>> upper 32 bits of the address returned are all 0's.
>
> That is not a good fix. usb_buffer_alloc() provides coherent memory,
> which is not what we want. I believe the correct fix is to specify the
> GFP_DMA32 flag in the kzalloc() call.

The traditional way to handle this is to leave it to swiotlb in
pci_map_*. pci_map_* is needed anyways if you run with a IOMMU.

Also note at least on x86 systems coherent memory is the same as non coherent
memory. And GFP_DMA32 is a x86 specific flag, doesn't necessarily
do any good anywhere else.

So if you add x86isms anyways you could as well use dma_alloc_coherent()
directly which is actually better at this than a simple GFP_DMA32
and as a bonus handles the IOMMUs correctly too.

Or just use GFP_KERNEL and pci_map_* later.

-Andi

--
[email protected] -- Speaking for myself only.

2010-04-12 10:49:24

by Daniel Mack

[permalink] [raw]
Subject: Re: [LKML] Re: USB transfer_buffer allocations on 64bit systems

On Fri, Apr 09, 2010 at 04:11:52PM -0600, Robert Hancock wrote:
> On Fri, Apr 9, 2010 at 3:23 PM, Alan Stern <[email protected]> wrote:
> > On Fri, 9 Apr 2010, Konrad Rzeszutek Wilk wrote:
> >
> >> On Fri, Apr 09, 2010 at 03:34:06PM -0400, Alan Stern wrote:
> >> > On Fri, 9 Apr 2010, Pedro Ribeiro wrote:
> >> >
> >> > > > The DMA pointers do indeed look sane. I wanted to take a deeper look at
> >> > > > this and set up a 64bit system today. However, I fail to see the problem
> >> > > > here. Pedro, how much RAM does your machine have installed?
> >> >
> >> > > It has 4 GB.
> >> >
> >> > That means DMA mapping cannot be the cause of the problem. ?:-(
> >>
> >> That isn't entirely true. The BIOS usually allocates a 256 MB ACPI/PCI hole
> >> that is under the 4GB.
> >>
> >> So end up with 3.7 GB, then the 256MB hole, and then right above the 4GB
> >> you the the remaining memory: 4.3GB.
> >
> > How can Pedro find out what physical addresses are in use on his
> > system?
>
> If you have 4GB of RAM then almost certainly you have memory located
> at addresses over 4GB. If you look at the e820 memory map printed at
> the start of dmesg on bootup and see entries with addresses of
> 100000000 or higher reported as usable, then this is the case.

Pedro, can you provide your dmesg output, please? I installed 5GB or RAM
to my machine now, and even with your .config, I can't see the problem.

Daniel

2010-04-12 11:14:45

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 10:59:57AM +0200, Andi Kleen wrote:
> Alan Stern <[email protected]> writes:
> >>
> >> The fix is to use usb_buffer_alloc() for that purpose which ensures
> >> memory that is suitable for DMA. And on x86_64, this also means that the
> >> upper 32 bits of the address returned are all 0's.
> >
> > That is not a good fix. usb_buffer_alloc() provides coherent memory,
> > which is not what we want. I believe the correct fix is to specify the
> > GFP_DMA32 flag in the kzalloc() call.
>
> The traditional way to handle this is to leave it to swiotlb in
> pci_map_*. pci_map_* is needed anyways if you run with a IOMMU.
>
> Also note at least on x86 systems coherent memory is the same as non coherent
> memory. And GFP_DMA32 is a x86 specific flag, doesn't necessarily
> do any good anywhere else.
>
> So if you add x86isms anyways you could as well use dma_alloc_coherent()
> directly which is actually better at this than a simple GFP_DMA32
> and as a bonus handles the IOMMUs correctly too.

Which is exactly what usb_buffer_alloc() does already. So at least for
x86 you say this is the right thing to do? However, we don't necessarily
need coherent memory on other platforms, which is why I hessitate to
enforce that type of memory for all transfer_buffer allocations.

> Or just use GFP_KERNEL and pci_map_* later.

The USB core does this already, but at least on Pedro's machine, this
seems unsufficient. Unfortunately, I can't reproduce the issue yet, even
with more than 4GB of RAM installed.

Daniel

2010-04-12 11:17:48

by Daniel Mack

[permalink] [raw]
Subject: [PATCH] USB: rename usb_buffer_alloc() and usb_buffer_free()

For more clearance what the functions actually do,

usb_buffer_alloc() is renamed to usb_alloc_coherent()
usb_buffer_free() is renamed to usb_free_coherent()

They should only be used in code which really needs DMA coherency.

All call sites have been changed accordingly, except for staging
drivers.

Signed-off-by: Daniel Mack <[email protected]>
Cc: Alan Stern <[email protected]>
Cc: Greg KH <[email protected]>
Cc: Pedro Ribeiro <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
Documentation/DocBook/writing_usb_driver.tmpl | 2 +-
Documentation/usb/dma.txt | 4 +-
drivers/hid/usbhid/hid-core.c | 16 +++++-----
drivers/hid/usbhid/usbkbd.c | 12 ++++----
drivers/hid/usbhid/usbmouse.c | 6 ++--
drivers/input/joystick/xpad.c | 16 +++++-----
drivers/input/misc/ati_remote.c | 12 ++++----
drivers/input/misc/ati_remote2.c | 4 +-
drivers/input/misc/cm109.c | 24 +++++++-------
drivers/input/misc/keyspan_remote.c | 6 ++--
drivers/input/misc/powermate.c | 16 +++++-----
drivers/input/misc/yealink.c | 24 +++++++-------
drivers/input/mouse/appletouch.c | 12 ++++----
drivers/input/mouse/bcm5974.c | 24 +++++++-------
drivers/input/tablet/acecad.c | 6 ++--
drivers/input/tablet/aiptek.c | 14 ++++----
drivers/input/tablet/gtco.c | 12 ++++----
drivers/input/tablet/kbtab.c | 6 ++--
drivers/input/tablet/wacom_sys.c | 10 +++---
drivers/input/touchscreen/usbtouchscreen.c | 8 ++--
drivers/media/dvb/dvb-usb/usb-urb.c | 7 ++--
drivers/media/dvb/ttusb-dec/ttusb_dec.c | 6 ++--
drivers/media/video/au0828/au0828-video.c | 4 +-
drivers/media/video/cx231xx/cx231xx-core.c | 14 ++++----
drivers/media/video/em28xx/em28xx-core.c | 4 +-
drivers/media/video/gspca/benq.c | 4 +-
drivers/media/video/gspca/gspca.c | 30 +++++++++---------
drivers/media/video/hdpvr/hdpvr-video.c | 8 ++--
drivers/media/video/tlg2300/pd-video.c | 14 ++++----
drivers/media/video/usbvision/usbvision-core.c | 16 +++++-----
drivers/media/video/uvc/uvc_video.c | 4 +-
drivers/net/can/usb/ems_usb.c | 18 +++++-----
drivers/net/usb/kaweth.c | 12 ++++----
drivers/net/wireless/ath/ar9170/usb.c | 8 ++--
drivers/net/wireless/zd1211rw/zd_usb.c | 10 +++---
drivers/usb/class/cdc-acm.c | 22 +++++++-------
drivers/usb/class/cdc-wdm.c | 38 ++++++++++++------------
drivers/usb/class/usblp.c | 2 +-
drivers/usb/core/usb.c | 20 ++++++------
drivers/usb/misc/appledisplay.c | 6 ++--
drivers/usb/misc/ftdi-elan.c | 18 +++++-----
drivers/usb/misc/iowarrior.c | 12 ++++----
drivers/usb/misc/usblcd.c | 8 ++--
drivers/usb/misc/usbtest.c | 16 +++++-----
drivers/usb/storage/onetouch.c | 12 ++++----
drivers/usb/storage/usb.c | 12 ++++----
drivers/usb/usb-skeleton.c | 10 +++---
drivers/watchdog/pcwd_usb.c | 6 ++--
include/linux/usb.h | 6 ++--
sound/usb/midi.c | 14 ++++----
sound/usb/misc/ua101.c | 16 +++++-----
sound/usb/urb.c | 18 +++++-----
52 files changed, 315 insertions(+), 314 deletions(-)

diff --git a/Documentation/DocBook/writing_usb_driver.tmpl b/Documentation/DocBook/writing_usb_driver.tmpl
index eeff19c..bd97a13 100644
--- a/Documentation/DocBook/writing_usb_driver.tmpl
+++ b/Documentation/DocBook/writing_usb_driver.tmpl
@@ -342,7 +342,7 @@ static inline void skel_delete (struct usb_skel *dev)
{
kfree (dev->bulk_in_buffer);
if (dev->bulk_out_buffer != NULL)
- usb_buffer_free (dev->udev, dev->bulk_out_size,
+ usb_free_coherent (dev->udev, dev->bulk_out_size,
dev->bulk_out_buffer,
dev->write_urb->transfer_dma);
usb_free_urb (dev->write_urb);
diff --git a/Documentation/usb/dma.txt b/Documentation/usb/dma.txt
index cfdcd16..a37e59c 100644
--- a/Documentation/usb/dma.txt
+++ b/Documentation/usb/dma.txt
@@ -43,10 +43,10 @@ and effects like cache-trashing can impose subtle penalties.
kind of addresses to store in urb->transfer_buffer and urb->transfer_dma.
You'd also set URB_NO_TRANSFER_DMA_MAP in urb->transfer_flags:

- void *usb_buffer_alloc (struct usb_device *dev, size_t size,
+ void *usb_alloc_coherent (struct usb_device *dev, size_t size,
int mem_flags, dma_addr_t *dma);

- void usb_buffer_free (struct usb_device *dev, size_t size,
+ void usb_free_coherent (struct usb_device *dev, size_t size,
void *addr, dma_addr_t dma);

Most drivers should *NOT* be using these primitives; they don't need
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 56d06cd..8496f3a 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -783,13 +783,13 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;

- usbhid->inbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_KERNEL,
+ usbhid->inbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
&usbhid->inbuf_dma);
- usbhid->outbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_KERNEL,
+ usbhid->outbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
&usbhid->outbuf_dma);
- usbhid->cr = usb_buffer_alloc(dev, sizeof(*usbhid->cr), GFP_KERNEL,
+ usbhid->cr = usb_alloc_coherent(dev, sizeof(*usbhid->cr), GFP_KERNEL,
&usbhid->cr_dma);
- usbhid->ctrlbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_KERNEL,
+ usbhid->ctrlbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
&usbhid->ctrlbuf_dma);
if (!usbhid->inbuf || !usbhid->outbuf || !usbhid->cr ||
!usbhid->ctrlbuf)
@@ -844,10 +844,10 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;

- usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
- usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
- usb_buffer_free(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma);
- usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
+ usb_free_coherent(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
+ usb_free_coherent(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
+ usb_free_coherent(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma);
+ usb_free_coherent(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
}

static int usbhid_parse(struct hid_device *hid)
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index f843443..b86f866 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -197,11 +197,11 @@ static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
return -1;
if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL)))
return -1;
- if (!(kbd->new = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
+ if (!(kbd->new = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
return -1;
- if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), GFP_ATOMIC, &kbd->cr_dma)))
+ if (!(kbd->cr = usb_alloc_coherent(dev, sizeof(struct usb_ctrlrequest), GFP_ATOMIC, &kbd->cr_dma)))
return -1;
- if (!(kbd->leds = usb_buffer_alloc(dev, 1, GFP_ATOMIC, &kbd->leds_dma)))
+ if (!(kbd->leds = usb_alloc_coherent(dev, 1, GFP_ATOMIC, &kbd->leds_dma)))
return -1;

return 0;
@@ -211,9 +211,9 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
{
usb_free_urb(kbd->irq);
usb_free_urb(kbd->led);
- usb_buffer_free(dev, 8, kbd->new, kbd->new_dma);
- usb_buffer_free(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma);
- usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma);
+ usb_free_coherent(dev, 8, kbd->new, kbd->new_dma);
+ usb_free_coherent(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma);
+ usb_free_coherent(dev, 1, kbd->leds, kbd->leds_dma);
}

static int usb_kbd_probe(struct usb_interface *iface,
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c
index 72ab4b2..79b2bf8 100644
--- a/drivers/hid/usbhid/usbmouse.c
+++ b/drivers/hid/usbhid/usbmouse.c
@@ -142,7 +142,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
if (!mouse || !input_dev)
goto fail1;

- mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma);
+ mouse->data = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &mouse->data_dma);
if (!mouse->data)
goto fail1;

@@ -205,7 +205,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
fail3:
usb_free_urb(mouse->irq);
fail2:
- usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
+ usb_free_coherent(dev, 8, mouse->data, mouse->data_dma);
fail1:
input_free_device(input_dev);
kfree(mouse);
@@ -221,7 +221,7 @@ static void usb_mouse_disconnect(struct usb_interface *intf)
usb_kill_urb(mouse->irq);
input_unregister_device(mouse->dev);
usb_free_urb(mouse->irq);
- usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
+ usb_free_coherent(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
kfree(mouse);
}
}
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 9b3353b..c1087ce 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -533,8 +533,8 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
return 0;

- xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN,
- GFP_KERNEL, &xpad->odata_dma);
+ xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
+ GFP_KERNEL, &xpad->odata_dma);
if (!xpad->odata)
goto fail1;

@@ -554,7 +554,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)

return 0;

- fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
+ fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
fail1: return error;
}

@@ -568,7 +568,7 @@ static void xpad_deinit_output(struct usb_xpad *xpad)
{
if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) {
usb_free_urb(xpad->irq_out);
- usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
+ usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
xpad->odata, xpad->odata_dma);
}
}
@@ -788,8 +788,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
if (!xpad || !input_dev)
goto fail1;

- xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
- GFP_KERNEL, &xpad->idata_dma);
+ xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
+ GFP_KERNEL, &xpad->idata_dma);
if (!xpad->idata)
goto fail1;

@@ -942,7 +942,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
fail5: usb_kill_urb(xpad->irq_in);
fail4: usb_free_urb(xpad->irq_in);
fail3: xpad_deinit_output(xpad);
- fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
+ fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
fail1: input_free_device(input_dev);
kfree(xpad);
return error;
@@ -964,7 +964,7 @@ static void xpad_disconnect(struct usb_interface *intf)
usb_kill_urb(xpad->irq_in);
}
usb_free_urb(xpad->irq_in);
- usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
+ usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
xpad->idata, xpad->idata_dma);
kfree(xpad);
}
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c
index 614b65d..2b9a2c8 100644
--- a/drivers/input/misc/ati_remote.c
+++ b/drivers/input/misc/ati_remote.c
@@ -620,13 +620,13 @@ static void ati_remote_irq_in(struct urb *urb)
static int ati_remote_alloc_buffers(struct usb_device *udev,
struct ati_remote *ati_remote)
{
- ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC,
- &ati_remote->inbuf_dma);
+ ati_remote->inbuf = usb_alloc_coherent(udev, DATA_BUFSIZE, GFP_ATOMIC,
+ &ati_remote->inbuf_dma);
if (!ati_remote->inbuf)
return -1;

- ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC,
- &ati_remote->outbuf_dma);
+ ati_remote->outbuf = usb_alloc_coherent(udev, DATA_BUFSIZE, GFP_ATOMIC,
+ &ati_remote->outbuf_dma);
if (!ati_remote->outbuf)
return -1;

@@ -649,10 +649,10 @@ static void ati_remote_free_buffers(struct ati_remote *ati_remote)
usb_free_urb(ati_remote->irq_urb);
usb_free_urb(ati_remote->out_urb);

- usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+ usb_free_coherent(ati_remote->udev, DATA_BUFSIZE,
ati_remote->inbuf, ati_remote->inbuf_dma);

- usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+ usb_free_coherent(ati_remote->udev, DATA_BUFSIZE,
ati_remote->outbuf, ati_remote->outbuf_dma);
}

diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index 2124b99..e148749 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -589,7 +589,7 @@ static int ati_remote2_urb_init(struct ati_remote2 *ar2)
int i, pipe, maxp;

for (i = 0; i < 2; i++) {
- ar2->buf[i] = usb_buffer_alloc(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]);
+ ar2->buf[i] = usb_alloc_coherent(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]);
if (!ar2->buf[i])
return -ENOMEM;

@@ -617,7 +617,7 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)

for (i = 0; i < 2; i++) {
usb_free_urb(ar2->urb[i]);
- usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
+ usb_free_coherent(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
}
}

diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c
index 86457fe..635b7ac 100644
--- a/drivers/input/misc/cm109.c
+++ b/drivers/input/misc/cm109.c
@@ -630,14 +630,14 @@ static const struct usb_device_id cm109_usb_table[] = {
static void cm109_usb_cleanup(struct cm109_dev *dev)
{
if (dev->ctl_req)
- usb_buffer_free(dev->udev, sizeof(*(dev->ctl_req)),
- dev->ctl_req, dev->ctl_req_dma);
+ usb_free_coherent(dev->udev, sizeof(*(dev->ctl_req)),
+ dev->ctl_req, dev->ctl_req_dma);
if (dev->ctl_data)
- usb_buffer_free(dev->udev, USB_PKT_LEN,
- dev->ctl_data, dev->ctl_dma);
+ usb_free_coherent(dev->udev, USB_PKT_LEN,
+ dev->ctl_data, dev->ctl_dma);
if (dev->irq_data)
- usb_buffer_free(dev->udev, USB_PKT_LEN,
- dev->irq_data, dev->irq_dma);
+ usb_free_coherent(dev->udev, USB_PKT_LEN,
+ dev->irq_data, dev->irq_dma);

usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */
usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */
@@ -686,18 +686,18 @@ static int cm109_usb_probe(struct usb_interface *intf,
goto err_out;

/* allocate usb buffers */
- dev->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
- GFP_KERNEL, &dev->irq_dma);
+ dev->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN,
+ GFP_KERNEL, &dev->irq_dma);
if (!dev->irq_data)
goto err_out;

- dev->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
- GFP_KERNEL, &dev->ctl_dma);
+ dev->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN,
+ GFP_KERNEL, &dev->ctl_dma);
if (!dev->ctl_data)
goto err_out;

- dev->ctl_req = usb_buffer_alloc(udev, sizeof(*(dev->ctl_req)),
- GFP_KERNEL, &dev->ctl_req_dma);
+ dev->ctl_req = usb_alloc_coherent(udev, sizeof(*(dev->ctl_req)),
+ GFP_KERNEL, &dev->ctl_req_dma);
if (!dev->ctl_req)
goto err_out;

diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c
index 86afdd1..a93c525 100644
--- a/drivers/input/misc/keyspan_remote.c
+++ b/drivers/input/misc/keyspan_remote.c
@@ -464,7 +464,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
remote->in_endpoint = endpoint;
remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */

- remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma);
+ remote->in_buffer = usb_alloc_coherent(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma);
if (!remote->in_buffer) {
error = -ENOMEM;
goto fail1;
@@ -543,7 +543,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
return 0;

fail3: usb_free_urb(remote->irq_urb);
- fail2: usb_buffer_free(udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+ fail2: usb_free_coherent(udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
fail1: kfree(remote);
input_free_device(input_dev);

@@ -564,7 +564,7 @@ static void keyspan_disconnect(struct usb_interface *interface)
input_unregister_device(remote->input);
usb_kill_urb(remote->irq_urb);
usb_free_urb(remote->irq_urb);
- usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+ usb_free_coherent(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
kfree(remote);
}
}
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c
index 668913d..a0b00d6 100644
--- a/drivers/input/misc/powermate.c
+++ b/drivers/input/misc/powermate.c
@@ -276,13 +276,13 @@ static int powermate_input_event(struct input_dev *dev, unsigned int type, unsig

static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm)
{
- pm->data = usb_buffer_alloc(udev, POWERMATE_PAYLOAD_SIZE_MAX,
- GFP_ATOMIC, &pm->data_dma);
+ pm->data = usb_alloc_coherent(udev, POWERMATE_PAYLOAD_SIZE_MAX,
+ GFP_ATOMIC, &pm->data_dma);
if (!pm->data)
return -1;

- pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)),
- GFP_ATOMIC, &pm->configcr_dma);
+ pm->configcr = usb_alloc_coherent(udev, sizeof(*(pm->configcr)),
+ GFP_ATOMIC, &pm->configcr_dma);
if (!pm->configcr)
return -1;

@@ -291,10 +291,10 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev

static void powermate_free_buffers(struct usb_device *udev, struct powermate_device *pm)
{
- usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX,
- pm->data, pm->data_dma);
- usb_buffer_free(udev, sizeof(*(pm->configcr)),
- pm->configcr, pm->configcr_dma);
+ usb_free_coherent(udev, POWERMATE_PAYLOAD_SIZE_MAX,
+ pm->data, pm->data_dma);
+ usb_free_coherent(udev, sizeof(*(pm->configcr)),
+ pm->configcr, pm->configcr_dma);
}

/* Called whenever a USB device matching one in our supported devices table is connected */
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
index 93a22ac..f584985 100644
--- a/drivers/input/misc/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -836,12 +836,12 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
usb_free_urb(yld->urb_irq);
usb_free_urb(yld->urb_ctl);

- usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
- yld->ctl_req, yld->ctl_req_dma);
- usb_buffer_free(yld->udev, USB_PKT_LEN,
- yld->ctl_data, yld->ctl_dma);
- usb_buffer_free(yld->udev, USB_PKT_LEN,
- yld->irq_data, yld->irq_dma);
+ usb_free_coherent(yld->udev, sizeof(*(yld->ctl_req)),
+ yld->ctl_req, yld->ctl_req_dma);
+ usb_free_coherent(yld->udev, USB_PKT_LEN,
+ yld->ctl_data, yld->ctl_dma);
+ usb_free_coherent(yld->udev, USB_PKT_LEN,
+ yld->irq_data, yld->irq_dma);

kfree(yld);
return err;
@@ -886,18 +886,18 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
return usb_cleanup(yld, -ENOMEM);

/* allocate usb buffers */
- yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
- GFP_ATOMIC, &yld->irq_dma);
+ yld->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN,
+ GFP_ATOMIC, &yld->irq_dma);
if (yld->irq_data == NULL)
return usb_cleanup(yld, -ENOMEM);

- yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
- GFP_ATOMIC, &yld->ctl_dma);
+ yld->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN,
+ GFP_ATOMIC, &yld->ctl_dma);
if (!yld->ctl_data)
return usb_cleanup(yld, -ENOMEM);

- yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)),
- GFP_ATOMIC, &yld->ctl_req_dma);
+ yld->ctl_req = usb_alloc_coherent(udev, sizeof(*(yld->ctl_req)),
+ GFP_ATOMIC, &yld->ctl_req_dma);
if (yld->ctl_req == NULL)
return usb_cleanup(yld, -ENOMEM);

diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 53ec7dd..05edd75 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -806,8 +806,8 @@ static int atp_probe(struct usb_interface *iface,
if (!dev->urb)
goto err_free_devs;

- dev->data = usb_buffer_alloc(dev->udev, dev->info->datalen, GFP_KERNEL,
- &dev->urb->transfer_dma);
+ dev->data = usb_alloc_coherent(dev->udev, dev->info->datalen, GFP_KERNEL,
+ &dev->urb->transfer_dma);
if (!dev->data)
goto err_free_urb;

@@ -862,8 +862,8 @@ static int atp_probe(struct usb_interface *iface,
return 0;

err_free_buffer:
- usb_buffer_free(dev->udev, dev->info->datalen,
- dev->data, dev->urb->transfer_dma);
+ usb_free_coherent(dev->udev, dev->info->datalen,
+ dev->data, dev->urb->transfer_dma);
err_free_urb:
usb_free_urb(dev->urb);
err_free_devs:
@@ -881,8 +881,8 @@ static void atp_disconnect(struct usb_interface *iface)
if (dev) {
usb_kill_urb(dev->urb);
input_unregister_device(dev->input);
- usb_buffer_free(dev->udev, dev->info->datalen,
- dev->data, dev->urb->transfer_dma);
+ usb_free_coherent(dev->udev, dev->info->datalen,
+ dev->data, dev->urb->transfer_dma);
usb_free_urb(dev->urb);
kfree(dev);
}
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 4f8fe08..aa3359a 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -715,15 +715,15 @@ static int bcm5974_probe(struct usb_interface *iface,
if (!dev->tp_urb)
goto err_free_bt_urb;

- dev->bt_data = usb_buffer_alloc(dev->udev,
- dev->cfg.bt_datalen, GFP_KERNEL,
- &dev->bt_urb->transfer_dma);
+ dev->bt_data = usb_alloc_coherent(dev->udev,
+ dev->cfg.bt_datalen, GFP_KERNEL,
+ &dev->bt_urb->transfer_dma);
if (!dev->bt_data)
goto err_free_urb;

- dev->tp_data = usb_buffer_alloc(dev->udev,
- dev->cfg.tp_datalen, GFP_KERNEL,
- &dev->tp_urb->transfer_dma);
+ dev->tp_data = usb_alloc_coherent(dev->udev,
+ dev->cfg.tp_datalen, GFP_KERNEL,
+ &dev->tp_urb->transfer_dma);
if (!dev->tp_data)
goto err_free_bt_buffer;

@@ -765,10 +765,10 @@ static int bcm5974_probe(struct usb_interface *iface,
return 0;

err_free_buffer:
- usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
+ usb_free_coherent(dev->udev, dev->cfg.tp_datalen,
dev->tp_data, dev->tp_urb->transfer_dma);
err_free_bt_buffer:
- usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
+ usb_free_coherent(dev->udev, dev->cfg.bt_datalen,
dev->bt_data, dev->bt_urb->transfer_dma);
err_free_urb:
usb_free_urb(dev->tp_urb);
@@ -788,10 +788,10 @@ static void bcm5974_disconnect(struct usb_interface *iface)
usb_set_intfdata(iface, NULL);

input_unregister_device(dev->input);
- usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
- dev->tp_data, dev->tp_urb->transfer_dma);
- usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
- dev->bt_data, dev->bt_urb->transfer_dma);
+ usb_free_coherent(dev->udev, dev->cfg.tp_datalen,
+ dev->tp_data, dev->tp_urb->transfer_dma);
+ usb_free_coherent(dev->udev, dev->cfg.bt_datalen,
+ dev->bt_data, dev->bt_urb->transfer_dma);
usb_free_urb(dev->tp_urb);
usb_free_urb(dev->bt_urb);
kfree(dev);
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c
index 670c61c..c047016 100644
--- a/drivers/input/tablet/acecad.c
+++ b/drivers/input/tablet/acecad.c
@@ -155,7 +155,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
goto fail1;
}

- acecad->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &acecad->data_dma);
+ acecad->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &acecad->data_dma);
if (!acecad->data) {
err= -ENOMEM;
goto fail1;
@@ -241,7 +241,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_

return 0;

- fail2: usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
+ fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma);
fail1: input_free_device(input_dev);
kfree(acecad);
return err;
@@ -256,7 +256,7 @@ static void usb_acecad_disconnect(struct usb_interface *intf)
usb_kill_urb(acecad->irq);
input_unregister_device(acecad->input);
usb_free_urb(acecad->irq);
- usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
+ usb_free_coherent(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
kfree(acecad);
}
}
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
index 4be039d..51b80b0 100644
--- a/drivers/input/tablet/aiptek.c
+++ b/drivers/input/tablet/aiptek.c
@@ -1711,8 +1711,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
goto fail1;
}

- aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
- GFP_ATOMIC, &aiptek->data_dma);
+ aiptek->data = usb_alloc_coherent(usbdev, AIPTEK_PACKET_LENGTH,
+ GFP_ATOMIC, &aiptek->data_dma);
if (!aiptek->data) {
dev_warn(&intf->dev, "cannot allocate usb buffer\n");
goto fail1;
@@ -1884,8 +1884,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)

fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
fail3: usb_free_urb(aiptek->urb);
- fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
- aiptek->data_dma);
+ fail2: usb_free_coherent(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
+ aiptek->data_dma);
fail1: usb_set_intfdata(intf, NULL);
input_free_device(inputdev);
kfree(aiptek);
@@ -1909,9 +1909,9 @@ static void aiptek_disconnect(struct usb_interface *intf)
input_unregister_device(aiptek->inputdev);
sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
usb_free_urb(aiptek->urb);
- usb_buffer_free(interface_to_usbdev(intf),
- AIPTEK_PACKET_LENGTH,
- aiptek->data, aiptek->data_dma);
+ usb_free_coherent(interface_to_usbdev(intf),
+ AIPTEK_PACKET_LENGTH,
+ aiptek->data, aiptek->data_dma);
kfree(aiptek);
}
}
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
index 866a9ee..8ea6afe 100644
--- a/drivers/input/tablet/gtco.c
+++ b/drivers/input/tablet/gtco.c
@@ -850,8 +850,8 @@ static int gtco_probe(struct usb_interface *usbinterface,
gtco->usbdev = usb_get_dev(interface_to_usbdev(usbinterface));

/* Allocate some data for incoming reports */
- gtco->buffer = usb_buffer_alloc(gtco->usbdev, REPORT_MAX_SIZE,
- GFP_KERNEL, &gtco->buf_dma);
+ gtco->buffer = usb_alloc_coherent(gtco->usbdev, REPORT_MAX_SIZE,
+ GFP_KERNEL, &gtco->buf_dma);
if (!gtco->buffer) {
err("No more memory for us buffers");
error = -ENOMEM;
@@ -982,8 +982,8 @@ static int gtco_probe(struct usb_interface *usbinterface,
err_free_urb:
usb_free_urb(gtco->urbinfo);
err_free_buf:
- usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE,
- gtco->buffer, gtco->buf_dma);
+ usb_free_coherent(gtco->usbdev, REPORT_MAX_SIZE,
+ gtco->buffer, gtco->buf_dma);
err_free_devs:
input_free_device(input_dev);
kfree(gtco);
@@ -1005,8 +1005,8 @@ static void gtco_disconnect(struct usb_interface *interface)
input_unregister_device(gtco->inputdevice);
usb_kill_urb(gtco->urbinfo);
usb_free_urb(gtco->urbinfo);
- usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE,
- gtco->buffer, gtco->buf_dma);
+ usb_free_coherent(gtco->usbdev, REPORT_MAX_SIZE,
+ gtco->buffer, gtco->buf_dma);
kfree(gtco);
}

diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c
index 6682b17..d31b9c7 100644
--- a/drivers/input/tablet/kbtab.c
+++ b/drivers/input/tablet/kbtab.c
@@ -129,7 +129,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
if (!kbtab || !input_dev)
goto fail1;

- kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma);
+ kbtab->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &kbtab->data_dma);
if (!kbtab->data)
goto fail1;

@@ -182,7 +182,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
return 0;

fail3: usb_free_urb(kbtab->irq);
- fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
+ fail2: usb_free_coherent(dev, 10, kbtab->data, kbtab->data_dma);
fail1: input_free_device(input_dev);
kfree(kbtab);
return error;
@@ -197,7 +197,7 @@ static void kbtab_disconnect(struct usb_interface *intf)
usb_kill_urb(kbtab->irq);
input_unregister_device(kbtab->dev);
usb_free_urb(kbtab->irq);
- usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
+ usb_free_coherent(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
kfree(kbtab);
}
}
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 8b5d287..5d5b3c3 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -556,8 +556,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
goto fail1;
}

- wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX,
- GFP_KERNEL, &wacom->data_dma);
+ wacom_wac->data = usb_alloc_coherent(dev, WACOM_PKGLEN_MAX,
+ GFP_KERNEL, &wacom->data_dma);
if (!wacom_wac->data) {
error = -ENOMEM;
goto fail1;
@@ -633,7 +633,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
return 0;

fail3: usb_free_urb(wacom->irq);
- fail2: usb_buffer_free(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma);
+ fail2: usb_free_coherent(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma);
fail1: input_free_device(input_dev);
kfree(wacom);
kfree(wacom_wac);
@@ -649,8 +649,8 @@ static void wacom_disconnect(struct usb_interface *intf)
usb_kill_urb(wacom->irq);
input_unregister_device(wacom->dev);
usb_free_urb(wacom->irq);
- usb_buffer_free(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
- wacom->wacom_wac->data, wacom->data_dma);
+ usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
+ wacom->wacom_wac->data, wacom->data_dma);
kfree(wacom->wacom_wac);
kfree(wacom);
}
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 99330bb..ea41a85 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -1291,8 +1291,8 @@ static void usbtouch_close(struct input_dev *input)
static void usbtouch_free_buffers(struct usb_device *udev,
struct usbtouch_usb *usbtouch)
{
- usb_buffer_free(udev, usbtouch->type->rept_size,
- usbtouch->data, usbtouch->data_dma);
+ usb_free_coherent(udev, usbtouch->type->rept_size,
+ usbtouch->data, usbtouch->data_dma);
kfree(usbtouch->buffer);
}

@@ -1336,8 +1336,8 @@ static int usbtouch_probe(struct usb_interface *intf,
if (!type->process_pkt)
type->process_pkt = usbtouch_process_pkt;

- usbtouch->data = usb_buffer_alloc(udev, type->rept_size,
- GFP_KERNEL, &usbtouch->data_dma);
+ usbtouch->data = usb_alloc_coherent(udev, type->rept_size,
+ GFP_KERNEL, &usbtouch->data_dma);
if (!usbtouch->data)
goto out_free;

diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c
index f9702e3..86d6893 100644
--- a/drivers/media/dvb/dvb-usb/usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/usb-urb.c
@@ -96,8 +96,9 @@ static int usb_free_stream_buffers(struct usb_data_stream *stream)
while (stream->buf_num) {
stream->buf_num--;
deb_mem("freeing buffer %d\n",stream->buf_num);
- usb_buffer_free(stream->udev, stream->buf_size,
- stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]);
+ usb_free_coherent(stream->udev, stream->buf_size,
+ stream->buf_list[stream->buf_num],
+ stream->dma_addr[stream->buf_num]);
}
}

@@ -116,7 +117,7 @@ static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num,
for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
deb_mem("allocating buffer %d\n",stream->buf_num);
if (( stream->buf_list[stream->buf_num] =
- usb_buffer_alloc(stream->udev, size, GFP_ATOMIC,
+ usb_alloc_coherent(stream->udev, size, GFP_ATOMIC,
&stream->dma_addr[stream->buf_num]) ) == NULL) {
deb_mem("not enough memory for urb-buffer allocation.\n");
usb_free_stream_buffers(stream);
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 53baccb..fe1b803 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1257,7 +1257,7 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec)
if(!dec->irq_urb) {
return -ENOMEM;
}
- dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE,
+ dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE,
GFP_ATOMIC, &dec->irq_dma_handle);
if(!dec->irq_buffer) {
usb_free_urb(dec->irq_urb);
@@ -1550,8 +1550,8 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec)

usb_free_urb(dec->irq_urb);

- usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
- dec->irq_buffer, dec->irq_dma_handle);
+ usb_free_coherent(dec->udev,IRQ_PACKET_SIZE,
+ dec->irq_buffer, dec->irq_dma_handle);

if (dec->rc_input_dev) {
input_unregister_device(dec->rc_input_dev);
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 8c140c0..a2a0f79 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -177,7 +177,7 @@ void au0828_uninit_isoc(struct au0828_dev *dev)
usb_unlink_urb(urb);

if (dev->isoc_ctl.transfer_buffer[i]) {
- usb_buffer_free(dev->usbdev,
+ usb_free_coherent(dev->usbdev,
urb->transfer_buffer_length,
dev->isoc_ctl.transfer_buffer[i],
urb->transfer_dma);
@@ -247,7 +247,7 @@ int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
}
dev->isoc_ctl.urb[i] = urb;

- dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->usbdev,
+ dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->usbdev,
sb_size, GFP_KERNEL, &urb->transfer_dma);
if (!dev->isoc_ctl.transfer_buffer[i]) {
printk("unable to allocate %i bytes for transfer"
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
index b24eee1..6ccd87d 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -679,11 +679,11 @@ void cx231xx_uninit_isoc(struct cx231xx *dev)
usb_unlink_urb(urb);

if (dev->video_mode.isoc_ctl.transfer_buffer[i]) {
- usb_buffer_free(dev->udev,
- urb->transfer_buffer_length,
- dev->video_mode.isoc_ctl.
- transfer_buffer[i],
- urb->transfer_dma);
+ usb_free_coherent(dev->udev,
+ urb->transfer_buffer_length,
+ dev->video_mode.isoc_ctl.
+ transfer_buffer[i],
+ urb->transfer_dma);
}
usb_free_urb(urb);
dev->video_mode.isoc_ctl.urb[i] = NULL;
@@ -770,8 +770,8 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
dev->video_mode.isoc_ctl.urb[i] = urb;

dev->video_mode.isoc_ctl.transfer_buffer[i] =
- usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,
- &urb->transfer_dma);
+ usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL,
+ &urb->transfer_dma);
if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) {
cx231xx_err("unable to allocate %i bytes for transfer"
" buffer %i%s\n",
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index a41cc55..d4a9554 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -966,7 +966,7 @@ void em28xx_uninit_isoc(struct em28xx *dev)
usb_unlink_urb(urb);

if (dev->isoc_ctl.transfer_buffer[i]) {
- usb_buffer_free(dev->udev,
+ usb_free_coherent(dev->udev,
urb->transfer_buffer_length,
dev->isoc_ctl.transfer_buffer[i],
urb->transfer_dma);
@@ -1041,7 +1041,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
}
dev->isoc_ctl.urb[i] = urb;

- dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->udev,
+ dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev,
sb_size, GFP_KERNEL, &urb->transfer_dma);
if (!dev->isoc_ctl.transfer_buffer[i]) {
em28xx_err("unable to allocate %i bytes for transfer"
diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c
index 43ac4af..fce8d94 100644
--- a/drivers/media/video/gspca/benq.c
+++ b/drivers/media/video/gspca/benq.c
@@ -117,13 +117,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
return -ENOMEM;
}
gspca_dev->urb[n] = urb;
- urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
+ urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev,
SD_PKT_SZ * SD_NPKT,
GFP_KERNEL,
&urb->transfer_dma);

if (urb->transfer_buffer == NULL) {
- err("usb_buffer_alloc failed");
+ err("usb_alloc_coherent failed");
return -ENOMEM;
}
urb->dev = gspca_dev->dev;
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 222af47..00713f8 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -213,7 +213,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
goto error;
}

- buffer = usb_buffer_alloc(dev, ep->wMaxPacketSize,
+ buffer = usb_alloc_coherent(dev, ep->wMaxPacketSize,
GFP_KERNEL, &urb->transfer_dma);
if (!buffer) {
ret = -ENOMEM;
@@ -232,10 +232,10 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
return ret;

error_submit:
- usb_buffer_free(dev,
- urb->transfer_buffer_length,
- urb->transfer_buffer,
- urb->transfer_dma);
+ usb_free_coherent(dev,
+ urb->transfer_buffer_length,
+ urb->transfer_buffer,
+ urb->transfer_dma);
error_buffer:
usb_free_urb(urb);
error:
@@ -272,10 +272,10 @@ static void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)
if (urb) {
gspca_dev->int_urb = NULL;
usb_kill_urb(urb);
- usb_buffer_free(gspca_dev->dev,
- urb->transfer_buffer_length,
- urb->transfer_buffer,
- urb->transfer_dma);
+ usb_free_coherent(gspca_dev->dev,
+ urb->transfer_buffer_length,
+ urb->transfer_buffer,
+ urb->transfer_dma);
usb_free_urb(urb);
}
}
@@ -597,10 +597,10 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
gspca_dev->urb[i] = NULL;
usb_kill_urb(urb);
if (urb->transfer_buffer != NULL)
- usb_buffer_free(gspca_dev->dev,
- urb->transfer_buffer_length,
- urb->transfer_buffer,
- urb->transfer_dma);
+ usb_free_coherent(gspca_dev->dev,
+ urb->transfer_buffer_length,
+ urb->transfer_buffer,
+ urb->transfer_dma);
usb_free_urb(urb);
}
}
@@ -721,13 +721,13 @@ static int create_urbs(struct gspca_dev *gspca_dev,
return -ENOMEM;
}
gspca_dev->urb[n] = urb;
- urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
+ urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev,
bsize,
GFP_KERNEL,
&urb->transfer_dma);

if (urb->transfer_buffer == NULL) {
- err("usb_buffer_alloc failed");
+ err("usb_alloc_coherent failed");
return -ENOMEM;
}
urb->dev = gspca_dev->dev;
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 196f82d..b65efe2 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -92,8 +92,8 @@ static int hdpvr_free_queue(struct list_head *q)
buf = list_entry(p, struct hdpvr_buffer, buff_list);

urb = buf->urb;
- usb_buffer_free(urb->dev, urb->transfer_buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
usb_free_urb(urb);
tmp = p->next;
list_del(p);
@@ -143,8 +143,8 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
}
buf->urb = urb;

- mem = usb_buffer_alloc(dev->udev, dev->bulk_in_size, GFP_KERNEL,
- &urb->transfer_dma);
+ mem = usb_alloc_coherent(dev->udev, dev->bulk_in_size, GFP_KERNEL,
+ &urb->transfer_dma);
if (!mem) {
v4l2_err(&dev->v4l2_dev,
"cannot allocate usb transfer buffer\n");
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
index cf8f18c..7bc2906 100644
--- a/drivers/media/video/tlg2300/pd-video.c
+++ b/drivers/media/video/tlg2300/pd-video.c
@@ -476,10 +476,10 @@ static int prepare_iso_urb(struct video_data *video)
goto out;

video->urb_array[i] = urb;
- mem = usb_buffer_alloc(udev,
- ISO_PKT_SIZE * PK_PER_URB,
- GFP_KERNEL,
- &urb->transfer_dma);
+ mem = usb_alloc_coherent(udev,
+ ISO_PKT_SIZE * PK_PER_URB,
+ GFP_KERNEL,
+ &urb->transfer_dma);

urb->complete = urb_complete_iso; /* handler */
urb->dev = udev;
@@ -519,8 +519,8 @@ int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
if (urb == NULL)
return i;

- mem = usb_buffer_alloc(udev, buf_size, gfp_flags,
- &urb->transfer_dma);
+ mem = usb_alloc_coherent(udev, buf_size, gfp_flags,
+ &urb->transfer_dma);
if (mem == NULL)
return i;

@@ -540,7 +540,7 @@ void free_all_urb_generic(struct urb **urb_array, int num)
for (i = 0; i < num; i++) {
urb = urb_array[i];
if (urb) {
- usb_buffer_free(urb->dev,
+ usb_free_coherent(urb->dev,
urb->transfer_buffer_length,
urb->transfer_buffer,
urb->transfer_dma);
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index f7aae22..b9dd74f 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -2493,10 +2493,10 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
}
usbvision->sbuf[bufIdx].urb = urb;
usbvision->sbuf[bufIdx].data =
- usb_buffer_alloc(usbvision->dev,
- sb_size,
- GFP_KERNEL,
- &urb->transfer_dma);
+ usb_alloc_coherent(usbvision->dev,
+ sb_size,
+ GFP_KERNEL,
+ &urb->transfer_dma);
urb->dev = dev;
urb->context = usbvision;
urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
@@ -2552,10 +2552,10 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
usb_kill_urb(usbvision->sbuf[bufIdx].urb);
if (usbvision->sbuf[bufIdx].data){
- usb_buffer_free(usbvision->dev,
- sb_size,
- usbvision->sbuf[bufIdx].data,
- usbvision->sbuf[bufIdx].urb->transfer_dma);
+ usb_free_coherent(usbvision->dev,
+ sb_size,
+ usbvision->sbuf[bufIdx].data,
+ usbvision->sbuf[bufIdx].urb->transfer_dma);
}
usb_free_urb(usbvision->sbuf[bufIdx].urb);
usbvision->sbuf[bufIdx].urb = NULL;
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 821a996..53f3ef4 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -739,7 +739,7 @@ static void uvc_free_urb_buffers(struct uvc_streaming *stream)

for (i = 0; i < UVC_URBS; ++i) {
if (stream->urb_buffer[i]) {
- usb_buffer_free(stream->dev->udev, stream->urb_size,
+ usb_free_coherent(stream->dev->udev, stream->urb_size,
stream->urb_buffer[i], stream->urb_dma[i]);
stream->urb_buffer[i] = NULL;
}
@@ -780,7 +780,7 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
for (; npackets > 1; npackets /= 2) {
for (i = 0; i < UVC_URBS; ++i) {
stream->urb_size = psize * npackets;
- stream->urb_buffer[i] = usb_buffer_alloc(
+ stream->urb_buffer[i] = usb_alloc_coherent(
stream->dev->udev, stream->urb_size,
gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]);
if (!stream->urb_buffer[i]) {
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 3345109..62be62f 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -516,8 +516,8 @@ static void ems_usb_write_bulk_callback(struct urb *urb)
netdev = dev->netdev;

/* free up our allocated buffer */
- usb_buffer_free(urb->dev, urb->transfer_buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);

atomic_dec(&dev->active_tx_urbs);

@@ -614,8 +614,8 @@ static int ems_usb_start(struct ems_usb *dev)
return -ENOMEM;
}

- buf = usb_buffer_alloc(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
- &urb->transfer_dma);
+ buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
+ &urb->transfer_dma);
if (!buf) {
dev_err(netdev->dev.parent,
"No memory left for USB buffer\n");
@@ -635,8 +635,8 @@ static int ems_usb_start(struct ems_usb *dev)
netif_device_detach(dev->netdev);

usb_unanchor_urb(urb);
- usb_buffer_free(dev->udev, RX_BUFFER_SIZE, buf,
- urb->transfer_dma);
+ usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
+ urb->transfer_dma);
break;
}

@@ -777,7 +777,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
goto nomem;
}

- buf = usb_buffer_alloc(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma);
+ buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma);
if (!buf) {
dev_err(netdev->dev.parent, "No memory left for USB buffer\n");
usb_free_urb(urb);
@@ -820,7 +820,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
*/
if (!context) {
usb_unanchor_urb(urb);
- usb_buffer_free(dev->udev, size, buf, urb->transfer_dma);
+ usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);

dev_warn(netdev->dev.parent, "couldn't find free context\n");

@@ -845,7 +845,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
can_free_echo_skb(netdev, context->echo_index);

usb_unanchor_urb(urb);
- usb_buffer_free(dev->udev, size, buf, urb->transfer_dma);
+ usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
dev_kfree_skb(skb);

atomic_dec(&dev->active_tx_urbs);
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index 52671ea..a790a6d 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -1155,13 +1155,13 @@ err_fw:
if (!kaweth->irq_urb)
goto err_tx_and_rx;

- kaweth->intbuffer = usb_buffer_alloc( kaweth->dev,
+ kaweth->intbuffer = usb_alloc_coherent( kaweth->dev,
INTBUFFERSIZE,
GFP_KERNEL,
&kaweth->intbufferhandle);
if (!kaweth->intbuffer)
goto err_tx_and_rx_and_irq;
- kaweth->rx_buf = usb_buffer_alloc( kaweth->dev,
+ kaweth->rx_buf = usb_alloc_coherent( kaweth->dev,
KAWETH_BUF_SIZE,
GFP_KERNEL,
&kaweth->rxbufferhandle);
@@ -1202,9 +1202,9 @@ err_fw:

err_intfdata:
usb_set_intfdata(intf, NULL);
- usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
+ usb_free_coherent(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
err_all_but_rxbuf:
- usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
+ usb_free_coherent(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
err_tx_and_rx_and_irq:
usb_free_urb(kaweth->irq_urb);
err_tx_and_rx:
@@ -1241,8 +1241,8 @@ static void kaweth_disconnect(struct usb_interface *intf)
usb_free_urb(kaweth->tx_urb);
usb_free_urb(kaweth->irq_urb);

- usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
- usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
+ usb_free_coherent(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
+ usb_free_coherent(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);

free_netdev(netdev);
}
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index 0b0d2dc..14eda1d 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -200,7 +200,7 @@ resubmit:
return;

free:
- usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
+ usb_free_coherent(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
}

static void ar9170_usb_rx_completed(struct urb *urb)
@@ -281,7 +281,7 @@ static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
if (!urb)
goto out;

- ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
+ ibuf = usb_alloc_coherent(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
if (!ibuf)
goto out;

@@ -294,8 +294,8 @@ static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
err = usb_submit_urb(urb, GFP_KERNEL);
if (err) {
usb_unanchor_urb(urb);
- usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
- urb->transfer_dma);
+ usb_free_coherent(aru->udev, 64, urb->transfer_buffer,
+ urb->transfer_dma);
}

out:
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index d91ad1a..c257940 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -664,15 +664,15 @@ static struct urb *alloc_rx_urb(struct zd_usb *usb)
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return NULL;
- buffer = usb_buffer_alloc(udev, USB_MAX_RX_SIZE, GFP_KERNEL,
- &urb->transfer_dma);
+ buffer = usb_alloc_coherent(udev, USB_MAX_RX_SIZE, GFP_KERNEL,
+ &urb->transfer_dma);
if (!buffer) {
usb_free_urb(urb);
return NULL;
}

usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, EP_DATA_IN),
- buffer, USB_MAX_RX_SIZE,
+ buffer, USB_MAX_RX_SIZE,
rx_urb_complete, usb);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

@@ -683,8 +683,8 @@ static void free_rx_urb(struct urb *urb)
{
if (!urb)
return;
- usb_buffer_free(urb->dev, urb->transfer_buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
usb_free_urb(urb);
}

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index be6331e..66713ed 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -892,7 +892,7 @@ static void acm_write_buffers_free(struct acm *acm)
struct usb_device *usb_dev = interface_to_usbdev(acm->control);

for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++)
- usb_buffer_free(usb_dev, acm->writesize, wb->buf, wb->dmah);
+ usb_free_coherent(usb_dev, acm->writesize, wb->buf, wb->dmah);
}

static void acm_read_buffers_free(struct acm *acm)
@@ -901,8 +901,8 @@ static void acm_read_buffers_free(struct acm *acm)
int i, n = acm->rx_buflimit;

for (i = 0; i < n; i++)
- usb_buffer_free(usb_dev, acm->readsize,
- acm->rb[i].base, acm->rb[i].dma);
+ usb_free_coherent(usb_dev, acm->readsize,
+ acm->rb[i].base, acm->rb[i].dma);
}

/* Little helper: write buffers allocate */
@@ -912,13 +912,13 @@ static int acm_write_buffers_alloc(struct acm *acm)
struct acm_wb *wb;

for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
- wb->buf = usb_buffer_alloc(acm->dev, acm->writesize, GFP_KERNEL,
+ wb->buf = usb_alloc_coherent(acm->dev, acm->writesize, GFP_KERNEL,
&wb->dmah);
if (!wb->buf) {
while (i != 0) {
--i;
--wb;
- usb_buffer_free(acm->dev, acm->writesize,
+ usb_free_coherent(acm->dev, acm->writesize,
wb->buf, wb->dmah);
}
return -ENOMEM;
@@ -1177,7 +1177,7 @@ made_compressed_probe:
tty_port_init(&acm->port);
acm->port.ops = &acm_port_ops;

- buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
+ buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
if (!buf) {
dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n");
goto alloc_fail2;
@@ -1210,11 +1210,11 @@ made_compressed_probe:
for (i = 0; i < num_rx_buf; i++) {
struct acm_rb *rb = &(acm->rb[i]);

- rb->base = usb_buffer_alloc(acm->dev, readsize,
+ rb->base = usb_alloc_coherent(acm->dev, readsize,
GFP_KERNEL, &rb->dma);
if (!rb->base) {
dev_dbg(&intf->dev,
- "out of memory (read bufs usb_buffer_alloc)\n");
+ "out of memory (read bufs usb_alloc_coherent)\n");
goto alloc_fail7;
}
}
@@ -1306,7 +1306,7 @@ alloc_fail7:
alloc_fail5:
acm_write_buffers_free(acm);
alloc_fail4:
- usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
+ usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
alloc_fail2:
kfree(acm);
alloc_fail:
@@ -1356,8 +1356,8 @@ static void acm_disconnect(struct usb_interface *intf)
stop_data_traffic(acm);

acm_write_buffers_free(acm);
- usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer,
- acm->ctrl_dma);
+ usb_free_coherent(usb_dev, acm->ctrlsize, acm->ctrl_buffer,
+ acm->ctrl_dma);
acm_read_buffers_free(acm);

if (!acm->combined_interfaces)
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 189141c..094c76b 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -276,14 +276,14 @@ static void free_urbs(struct wdm_device *desc)

static void cleanup(struct wdm_device *desc)
{
- usb_buffer_free(interface_to_usbdev(desc->intf),
- desc->wMaxPacketSize,
- desc->sbuf,
- desc->validity->transfer_dma);
- usb_buffer_free(interface_to_usbdev(desc->intf),
- desc->wMaxCommand,
- desc->inbuf,
- desc->response->transfer_dma);
+ usb_free_coherent(interface_to_usbdev(desc->intf),
+ desc->wMaxPacketSize,
+ desc->sbuf,
+ desc->validity->transfer_dma);
+ usb_free_coherent(interface_to_usbdev(desc->intf),
+ desc->wMaxCommand,
+ desc->inbuf,
+ desc->response->transfer_dma);
kfree(desc->orq);
kfree(desc->irq);
kfree(desc->ubuf);
@@ -705,17 +705,17 @@ next_desc:
if (!desc->ubuf)
goto err;

- desc->sbuf = usb_buffer_alloc(interface_to_usbdev(intf),
+ desc->sbuf = usb_alloc_coherent(interface_to_usbdev(intf),
desc->wMaxPacketSize,
GFP_KERNEL,
&desc->validity->transfer_dma);
if (!desc->sbuf)
goto err;

- desc->inbuf = usb_buffer_alloc(interface_to_usbdev(intf),
- desc->bMaxPacketSize0,
- GFP_KERNEL,
- &desc->response->transfer_dma);
+ desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf),
+ desc->bMaxPacketSize0,
+ GFP_KERNEL,
+ &desc->response->transfer_dma);
if (!desc->inbuf)
goto err2;

@@ -742,15 +742,15 @@ out:
return rv;
err3:
usb_set_intfdata(intf, NULL);
- usb_buffer_free(interface_to_usbdev(desc->intf),
- desc->bMaxPacketSize0,
+ usb_free_coherent(interface_to_usbdev(desc->intf),
+ desc->bMaxPacketSize0,
desc->inbuf,
desc->response->transfer_dma);
err2:
- usb_buffer_free(interface_to_usbdev(desc->intf),
- desc->wMaxPacketSize,
- desc->sbuf,
- desc->validity->transfer_dma);
+ usb_free_coherent(interface_to_usbdev(desc->intf),
+ desc->wMaxPacketSize,
+ desc->sbuf,
+ desc->validity->transfer_dma);
err:
free_urbs(desc);
kfree(desc->ubuf);
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 93b5f85..2250095 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -27,7 +27,7 @@
* v0.11 - add proto_bias option (Pete Zaitcev)
* v0.12 - add hpoj.sourceforge.net ioctls (David Paschal)
* v0.13 - alloc space for statusbuf (<status> not on stack);
- * use usb_buffer_alloc() for read buf & write buf;
+ * use usb_alloc_coherent() for read buf & write buf;
* none - Maintained in Linux kernel after v0.13
*/

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 1297e9b..0561430 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -718,7 +718,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);

/**
- * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
+ * usb_alloc_coherent - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
* @dev: device the buffer will be used with
* @size: requested buffer size
* @mem_flags: affect whether allocation may block
@@ -737,30 +737,30 @@ EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
* architectures where CPU caches are not DMA-coherent. On systems without
* bus-snooping caches, these buffers are uncached.
*
- * When the buffer is no longer used, free it with usb_buffer_free().
+ * When the buffer is no longer used, free it with usb_free_coherent().
*/
-void *usb_buffer_alloc(struct usb_device *dev, size_t size, gfp_t mem_flags,
- dma_addr_t *dma)
+void *usb_alloc_coherent(struct usb_device *dev, size_t size, gfp_t mem_flags,
+ dma_addr_t *dma)
{
if (!dev || !dev->bus)
return NULL;
return hcd_buffer_alloc(dev->bus, size, mem_flags, dma);
}
-EXPORT_SYMBOL_GPL(usb_buffer_alloc);
+EXPORT_SYMBOL_GPL(usb_alloc_coherent);

/**
- * usb_buffer_free - free memory allocated with usb_buffer_alloc()
+ * usb_free_coherent - free memory allocated with usb_alloc_coherent()
* @dev: device the buffer was used with
* @size: requested buffer size
* @addr: CPU address of buffer
* @dma: DMA address of buffer
*
* This reclaims an I/O buffer, letting it be reused. The memory must have
- * been allocated using usb_buffer_alloc(), and the parameters must match
+ * been allocated using usb_alloc_coherent(), and the parameters must match
* those provided in that allocation request.
*/
-void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
- dma_addr_t dma)
+void usb_free_coherent(struct usb_device *dev, size_t size, void *addr,
+ dma_addr_t dma)
{
if (!dev || !dev->bus)
return;
@@ -768,7 +768,7 @@ void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
return;
hcd_buffer_free(dev->bus, size, addr, dma);
}
-EXPORT_SYMBOL_GPL(usb_buffer_free);
+EXPORT_SYMBOL_GPL(usb_free_coherent);

/**
* usb_buffer_map - create DMA mapping(s) for an urb
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index 094f91c..1fa6ce3 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -259,7 +259,7 @@ static int appledisplay_probe(struct usb_interface *iface,
}

/* Allocate buffer for interrupt data */
- pdata->urbdata = usb_buffer_alloc(pdata->udev, ACD_URB_BUFFER_LEN,
+ pdata->urbdata = usb_alloc_coherent(pdata->udev, ACD_URB_BUFFER_LEN,
GFP_KERNEL, &pdata->urb->transfer_dma);
if (!pdata->urbdata) {
retval = -ENOMEM;
@@ -316,7 +316,7 @@ error:
if (pdata->urb) {
usb_kill_urb(pdata->urb);
if (pdata->urbdata)
- usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN,
+ usb_free_coherent(pdata->udev, ACD_URB_BUFFER_LEN,
pdata->urbdata, pdata->urb->transfer_dma);
usb_free_urb(pdata->urb);
}
@@ -337,7 +337,7 @@ static void appledisplay_disconnect(struct usb_interface *iface)
usb_kill_urb(pdata->urb);
cancel_delayed_work(&pdata->work);
backlight_device_unregister(pdata->bd);
- usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN,
+ usb_free_coherent(pdata->udev, ACD_URB_BUFFER_LEN,
pdata->urbdata, pdata->urb->transfer_dma);
usb_free_urb(pdata->urb);
kfree(pdata->msgdata);
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 1edb6d3..a9e0546 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -734,7 +734,7 @@ static void ftdi_elan_write_bulk_callback(struct urb *urb)
dev_err(&ftdi->udev->dev, "urb=%p write bulk status received: %"
"d\n", urb, status);
}
- usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
urb->transfer_buffer, urb->transfer_dma);
}

@@ -795,7 +795,7 @@ static int ftdi_elan_command_engine(struct usb_ftdi *ftdi)
total_size);
return -ENOMEM;
}
- buf = usb_buffer_alloc(ftdi->udev, total_size, GFP_KERNEL,
+ buf = usb_alloc_coherent(ftdi->udev, total_size, GFP_KERNEL,
&urb->transfer_dma);
if (!buf) {
dev_err(&ftdi->udev->dev, "could not get a buffer to write %d c"
@@ -829,7 +829,7 @@ static int ftdi_elan_command_engine(struct usb_ftdi *ftdi)
dev_err(&ftdi->udev->dev, "failed %d to submit urb %p to write "
"%d commands totaling %d bytes to the Uxxx\n", retval,
urb, command_size, total_size);
- usb_buffer_free(ftdi->udev, total_size, buf, urb->transfer_dma);
+ usb_free_coherent(ftdi->udev, total_size, buf, urb->transfer_dma);
usb_free_urb(urb);
return retval;
}
@@ -1167,7 +1167,7 @@ static ssize_t ftdi_elan_write(struct file *file,
retval = -ENOMEM;
goto error_1;
}
- buf = usb_buffer_alloc(ftdi->udev, count, GFP_KERNEL,
+ buf = usb_alloc_coherent(ftdi->udev, count, GFP_KERNEL,
&urb->transfer_dma);
if (!buf) {
retval = -ENOMEM;
@@ -1192,7 +1192,7 @@ static ssize_t ftdi_elan_write(struct file *file,
exit:
return count;
error_3:
- usb_buffer_free(ftdi->udev, count, buf, urb->transfer_dma);
+ usb_free_coherent(ftdi->udev, count, buf, urb->transfer_dma);
error_2:
usb_free_urb(urb);
error_1:
@@ -1968,7 +1968,7 @@ static int ftdi_elan_synchronize_flush(struct usb_ftdi *ftdi)
"ence\n");
return -ENOMEM;
}
- buf = usb_buffer_alloc(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma);
+ buf = usb_alloc_coherent(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma);
if (!buf) {
dev_err(&ftdi->udev->dev, "could not get a buffer for flush seq"
"uence\n");
@@ -1985,7 +1985,7 @@ static int ftdi_elan_synchronize_flush(struct usb_ftdi *ftdi)
if (retval) {
dev_err(&ftdi->udev->dev, "failed to submit urb containing the "
"flush sequence\n");
- usb_buffer_free(ftdi->udev, i, buf, urb->transfer_dma);
+ usb_free_coherent(ftdi->udev, i, buf, urb->transfer_dma);
usb_free_urb(urb);
return -ENOMEM;
}
@@ -2011,7 +2011,7 @@ static int ftdi_elan_synchronize_reset(struct usb_ftdi *ftdi)
"quence\n");
return -ENOMEM;
}
- buf = usb_buffer_alloc(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma);
+ buf = usb_alloc_coherent(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma);
if (!buf) {
dev_err(&ftdi->udev->dev, "could not get a buffer for the reset"
" sequence\n");
@@ -2030,7 +2030,7 @@ static int ftdi_elan_synchronize_reset(struct usb_ftdi *ftdi)
if (retval) {
dev_err(&ftdi->udev->dev, "failed to submit urb containing the "
"reset sequence\n");
- usb_buffer_free(ftdi->udev, i, buf, urb->transfer_dma);
+ usb_free_coherent(ftdi->udev, i, buf, urb->transfer_dma);
usb_free_urb(urb);
return -ENOMEM;
}
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index d3c8523..7dc9d3c 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -239,8 +239,8 @@ static void iowarrior_write_callback(struct urb *urb)
__func__, status);
}
/* free up our allocated buffer */
- usb_buffer_free(urb->dev, urb->transfer_buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
/* tell a waiting writer the interrupt-out-pipe is available again */
atomic_dec(&dev->write_busy);
wake_up_interruptible(&dev->write_wait);
@@ -421,8 +421,8 @@ static ssize_t iowarrior_write(struct file *file,
dbg("%s Unable to allocate urb ", __func__);
goto error_no_urb;
}
- buf = usb_buffer_alloc(dev->udev, dev->report_size,
- GFP_KERNEL, &int_out_urb->transfer_dma);
+ buf = usb_alloc_coherent(dev->udev, dev->report_size,
+ GFP_KERNEL, &int_out_urb->transfer_dma);
if (!buf) {
retval = -ENOMEM;
dbg("%s Unable to allocate buffer ", __func__);
@@ -459,8 +459,8 @@ static ssize_t iowarrior_write(struct file *file,
break;
}
error:
- usb_buffer_free(dev->udev, dev->report_size, buf,
- int_out_urb->transfer_dma);
+ usb_free_coherent(dev->udev, dev->report_size, buf,
+ int_out_urb->transfer_dma);
error_no_buffer:
usb_free_urb(int_out_urb);
error_no_urb:
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index 90aede9..7828c76 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -205,8 +205,8 @@ static void lcd_write_bulk_callback(struct urb *urb)
}

/* free up our allocated buffer */
- usb_buffer_free(urb->dev, urb->transfer_buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
up(&dev->limit_sem);
}

@@ -234,7 +234,7 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz
goto err_no_buf;
}

- buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
+ buf = usb_alloc_coherent(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
if (!buf) {
retval = -ENOMEM;
goto error;
@@ -268,7 +268,7 @@ exit:
error_unanchor:
usb_unanchor_urb(urb);
error:
- usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
+ usb_free_coherent(dev->udev, count, buf, urb->transfer_dma);
usb_free_urb(urb);
err_no_buf:
up(&dev->limit_sem);
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index a21cce6..9ecde8c 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -202,7 +202,7 @@ static struct urb *simple_alloc_urb (
urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
if (usb_pipein (pipe))
urb->transfer_flags |= URB_SHORT_NOT_OK;
- urb->transfer_buffer = usb_buffer_alloc (udev, bytes, GFP_KERNEL,
+ urb->transfer_buffer = usb_alloc_coherent (udev, bytes, GFP_KERNEL,
&urb->transfer_dma);
if (!urb->transfer_buffer) {
usb_free_urb (urb);
@@ -272,8 +272,8 @@ static inline int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb)

static void simple_free_urb (struct urb *urb)
{
- usb_buffer_free (urb->dev, urb->transfer_buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
usb_free_urb (urb);
}

@@ -977,7 +977,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
if (!u)
goto cleanup;

- reqp = usb_buffer_alloc (udev, sizeof *reqp, GFP_KERNEL,
+ reqp = usb_alloc_coherent (udev, sizeof *reqp, GFP_KERNEL,
&u->setup_dma);
if (!reqp)
goto cleanup;
@@ -1018,9 +1018,9 @@ cleanup:
continue;
urb [i]->dev = udev;
if (urb [i]->setup_packet)
- usb_buffer_free (udev, sizeof (struct usb_ctrlrequest),
- urb [i]->setup_packet,
- urb [i]->setup_dma);
+ usb_free_coherent (udev, sizeof (struct usb_ctrlrequest),
+ urb [i]->setup_packet,
+ urb [i]->setup_dma);
simple_free_urb (urb [i]);
}
kfree (urb);
@@ -1421,7 +1421,7 @@ static struct urb *iso_alloc_urb (

urb->number_of_packets = packets;
urb->transfer_buffer_length = bytes;
- urb->transfer_buffer = usb_buffer_alloc (udev, bytes, GFP_KERNEL,
+ urb->transfer_buffer = usb_alloc_coherent (udev, bytes, GFP_KERNEL,
&urb->transfer_dma);
if (!urb->transfer_buffer) {
usb_free_urb (urb);
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 198bb3e..1943be5 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -201,8 +201,8 @@ static int onetouch_connect_input(struct us_data *ss)
if (!onetouch || !input_dev)
goto fail1;

- onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
- GFP_KERNEL, &onetouch->data_dma);
+ onetouch->data = usb_alloc_coherent(udev, ONETOUCH_PKT_LEN,
+ GFP_KERNEL, &onetouch->data_dma);
if (!onetouch->data)
goto fail1;

@@ -264,8 +264,8 @@ static int onetouch_connect_input(struct us_data *ss)
return 0;

fail3: usb_free_urb(onetouch->irq);
- fail2: usb_buffer_free(udev, ONETOUCH_PKT_LEN,
- onetouch->data, onetouch->data_dma);
+ fail2: usb_free_coherent(udev, ONETOUCH_PKT_LEN,
+ onetouch->data, onetouch->data_dma);
fail1: kfree(onetouch);
input_free_device(input_dev);
return error;
@@ -279,8 +279,8 @@ static void onetouch_release_input(void *onetouch_)
usb_kill_urb(onetouch->irq);
input_unregister_device(onetouch->dev);
usb_free_urb(onetouch->irq);
- usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN,
- onetouch->data, onetouch->data_dma);
+ usb_free_coherent(onetouch->udev, ONETOUCH_PKT_LEN,
+ onetouch->data, onetouch->data_dma);
}
}

diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index bbeeb92..ef00584 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -408,14 +408,14 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
usb_set_intfdata(intf, us);

/* Allocate the device-related DMA-mapped buffers */
- us->cr = usb_buffer_alloc(us->pusb_dev, sizeof(*us->cr),
+ us->cr = usb_alloc_coherent(us->pusb_dev, sizeof(*us->cr),
GFP_KERNEL, &us->cr_dma);
if (!us->cr) {
US_DEBUGP("usb_ctrlrequest allocation failed\n");
return -ENOMEM;
}

- us->iobuf = usb_buffer_alloc(us->pusb_dev, US_IOBUF_SIZE,
+ us->iobuf = usb_alloc_coherent(us->pusb_dev, US_IOBUF_SIZE,
GFP_KERNEL, &us->iobuf_dma);
if (!us->iobuf) {
US_DEBUGP("I/O buffer allocation failed\n");
@@ -759,11 +759,11 @@ static void dissociate_dev(struct us_data *us)

/* Free the device-related DMA-mapped buffers */
if (us->cr)
- usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr,
- us->cr_dma);
+ usb_free_coherent(us->pusb_dev, sizeof(*us->cr), us->cr,
+ us->cr_dma);
if (us->iobuf)
- usb_buffer_free(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,
- us->iobuf_dma);
+ usb_free_coherent(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,
+ us->iobuf_dma);

/* Remove our private data from the interface */
usb_set_intfdata(us->pusb_intf, NULL);
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 6152278..d110588 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -387,8 +387,8 @@ static void skel_write_bulk_callback(struct urb *urb)
}

/* free up our allocated buffer */
- usb_buffer_free(urb->dev, urb->transfer_buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
up(&dev->limit_sem);
}

@@ -442,8 +442,8 @@ static ssize_t skel_write(struct file *file, const char *user_buffer,
goto error;
}

- buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL,
- &urb->transfer_dma);
+ buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
+ &urb->transfer_dma);
if (!buf) {
retval = -ENOMEM;
goto error;
@@ -491,7 +491,7 @@ error_unanchor:
usb_unanchor_urb(urb);
error:
if (urb) {
- usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
+ usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
usb_free_urb(urb);
}
up(&dev->limit_sem);
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index 8e4eacc..748a74b 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -600,8 +600,8 @@ static inline void usb_pcwd_delete(struct usb_pcwd_private *usb_pcwd)
{
usb_free_urb(usb_pcwd->intr_urb);
if (usb_pcwd->intr_buffer != NULL)
- usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size,
- usb_pcwd->intr_buffer, usb_pcwd->intr_dma);
+ usb_free_coherent(usb_pcwd->udev, usb_pcwd->intr_size,
+ usb_pcwd->intr_buffer, usb_pcwd->intr_dma);
kfree(usb_pcwd);
}

@@ -671,7 +671,7 @@ static int usb_pcwd_probe(struct usb_interface *interface,
le16_to_cpu(endpoint->wMaxPacketSize) : 8);

/* set up the memory buffer's */
- usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size,
+ usb_pcwd->intr_buffer = usb_alloc_coherent(udev, usb_pcwd->intr_size,
GFP_ATOMIC, &usb_pcwd->intr_dma);
if (!usb_pcwd->intr_buffer) {
printk(KERN_ERR PFX "Out of memory\n");
diff --git a/include/linux/usb.h b/include/linux/usb.h
index ce1323c..4f485d0 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1085,7 +1085,7 @@ typedef void (*usb_complete_t)(struct urb *);
* Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
* which tell the host controller driver that no such mapping is needed since
* the device driver is DMA-aware. For example, a device driver might
- * allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
+ * allocate a DMA buffer with usb_alloc_coherent() or call usb_buffer_map().
* When these transfer flags are provided, host controller drivers will
* attempt to use the dma addresses found in the transfer_dma and/or
* setup_dma fields rather than determining a dma address themselves.
@@ -1366,9 +1366,9 @@ static inline int usb_urb_dir_out(struct urb *urb)
return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT;
}

-void *usb_buffer_alloc(struct usb_device *dev, size_t size,
+void *usb_alloc_coherent(struct usb_device *dev, size_t size,
gfp_t mem_flags, dma_addr_t *dma);
-void usb_buffer_free(struct usb_device *dev, size_t size,
+void usb_free_coherent(struct usb_device *dev, size_t size,
void *addr, dma_addr_t dma);

#if 0
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index c6ee4a1..00f7d8e 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1046,8 +1046,8 @@ static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb,
unsigned int buffer_length)
{
- usb_buffer_free(umidi->dev, buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
+ usb_free_coherent(umidi->dev, buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
usb_free_urb(urb);
}

@@ -1098,8 +1098,8 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep);
length = usb_maxpacket(umidi->dev, pipe, 0);
for (i = 0; i < INPUT_URBS; ++i) {
- buffer = usb_buffer_alloc(umidi->dev, length, GFP_KERNEL,
- &ep->urbs[i]->transfer_dma);
+ buffer = usb_alloc_coherent(umidi->dev, length, GFP_KERNEL,
+ &ep->urbs[i]->transfer_dma);
if (!buffer) {
snd_usbmidi_in_endpoint_delete(ep);
return -ENOMEM;
@@ -1182,9 +1182,9 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
break;
}
for (i = 0; i < OUTPUT_URBS; ++i) {
- buffer = usb_buffer_alloc(umidi->dev,
- ep->max_transfer, GFP_KERNEL,
- &ep->urbs[i].urb->transfer_dma);
+ buffer = usb_alloc_coherent(umidi->dev,
+ ep->max_transfer, GFP_KERNEL,
+ &ep->urbs[i].urb->transfer_dma);
if (!buffer) {
snd_usbmidi_out_endpoint_delete(ep);
return -ENOMEM;
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index 796d8b2..fb5d68f 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -42,7 +42,7 @@ MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}");
/*
* This magic value optimizes memory usage efficiency for the UA-101's packet
* sizes at all sample rates, taking into account the stupid cache pool sizes
- * that usb_buffer_alloc() uses.
+ * that usb_alloc_coherent() uses.
*/
#define DEFAULT_QUEUE_LENGTH 21

@@ -1057,7 +1057,7 @@ static int alloc_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
(unsigned int)MAX_QUEUE_LENGTH);

/*
- * The cache pool sizes used by usb_buffer_alloc() (128, 512, 2048) are
+ * The cache pool sizes used by usb_alloc_coherent() (128, 512, 2048) are
* quite bad when used with the packet sizes of this device (e.g. 280,
* 520, 624). Therefore, we allocate and subdivide entire pages, using
* a smaller buffer only for the last chunk.
@@ -1068,8 +1068,8 @@ static int alloc_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
packets = min(remaining_packets, packets_per_page);
size = packets * stream->max_packet_bytes;
stream->buffers[i].addr =
- usb_buffer_alloc(ua->dev, size, GFP_KERNEL,
- &stream->buffers[i].dma);
+ usb_alloc_coherent(ua->dev, size, GFP_KERNEL,
+ &stream->buffers[i].dma);
if (!stream->buffers[i].addr)
return -ENOMEM;
stream->buffers[i].size = size;
@@ -1089,10 +1089,10 @@ static void free_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
unsigned int i;

for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i)
- usb_buffer_free(ua->dev,
- stream->buffers[i].size,
- stream->buffers[i].addr,
- stream->buffers[i].dma);
+ usb_free_coherent(ua->dev,
+ stream->buffers[i].size,
+ stream->buffers[i].addr,
+ stream->buffers[i].dma);
}

static int alloc_stream_urbs(struct ua101 *ua, struct ua101_stream *stream,
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
index 5570a2b..8c7b3e5 100644
--- a/sound/usb/urb.c
+++ b/sound/usb/urb.c
@@ -101,9 +101,9 @@ static void release_urb_ctx(struct snd_urb_ctx *u)
{
if (u->urb) {
if (u->buffer_size)
- usb_buffer_free(u->subs->dev, u->buffer_size,
- u->urb->transfer_buffer,
- u->urb->transfer_dma);
+ usb_free_coherent(u->subs->dev, u->buffer_size,
+ u->urb->transfer_buffer,
+ u->urb->transfer_dma);
usb_free_urb(u->urb);
u->urb = NULL;
}
@@ -154,8 +154,8 @@ void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force)
release_urb_ctx(&subs->dataurb[i]);
for (i = 0; i < SYNC_URBS; i++)
release_urb_ctx(&subs->syncurb[i]);
- usb_buffer_free(subs->dev, SYNC_URBS * 4,
- subs->syncbuf, subs->sync_dma);
+ usb_free_coherent(subs->dev, SYNC_URBS * 4,
+ subs->syncbuf, subs->sync_dma);
subs->syncbuf = NULL;
subs->nurbs = 0;
}
@@ -308,8 +308,8 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
if (!u->urb)
goto out_of_memory;
u->urb->transfer_buffer =
- usb_buffer_alloc(subs->dev, u->buffer_size, GFP_KERNEL,
- &u->urb->transfer_dma);
+ usb_alloc_coherent(subs->dev, u->buffer_size, GFP_KERNEL,
+ &u->urb->transfer_dma);
if (!u->urb->transfer_buffer)
goto out_of_memory;
u->urb->pipe = subs->datapipe;
@@ -321,8 +321,8 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,

if (subs->syncpipe) {
/* allocate and initialize sync urbs */
- subs->syncbuf = usb_buffer_alloc(subs->dev, SYNC_URBS * 4,
- GFP_KERNEL, &subs->sync_dma);
+ subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4,
+ GFP_KERNEL, &subs->sync_dma);
if (!subs->syncbuf)
goto out_of_memory;
for (i = 0; i < SYNC_URBS; i++) {
--
1.6.6.1

2010-04-12 11:53:07

by Andi Kleen

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

> Which is exactly what usb_buffer_alloc() does already. So at least for
> x86 you say this is the right thing to do? However, we don't necessarily
> need coherent memory on other platforms, which is why I hessitate to
> enforce that type of memory for all transfer_buffer allocations.

Yes today it's faster at least.

Probably we should have better interfaces for this, but we don't.

>
> > Or just use GFP_KERNEL and pci_map_* later.
>
> The USB core does this already, but at least on Pedro's machine, this
> seems unsufficient. Unfortunately, I can't reproduce the issue yet, even
> with more than 4GB of RAM installed.

Then something must be broken in Pedro's system and likely other drivers
will also not work. I don't think it should be worked around in the USB layer.

-Andi
--
[email protected] -- Speaking for myself only.

2010-04-12 12:06:55

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: [LKML] Re: USB transfer_buffer allocations on 64bit systems

On 12 April 2010 11:48, Daniel Mack <[email protected]> wrote:
> On Fri, Apr 09, 2010 at 04:11:52PM -0600, Robert Hancock wrote:
>> On Fri, Apr 9, 2010 at 3:23 PM, Alan Stern <[email protected]> wrote:
>> > On Fri, 9 Apr 2010, Konrad Rzeszutek Wilk wrote:
>> >
>> >> On Fri, Apr 09, 2010 at 03:34:06PM -0400, Alan Stern wrote:
>> >> > On Fri, 9 Apr 2010, Pedro Ribeiro wrote:
>> >> >
>> >> > > > The DMA pointers do indeed look sane. I wanted to take a deeper look at
>> >> > > > this and set up a 64bit system today. However, I fail to see the problem
>> >> > > > here. Pedro, how much RAM does your machine have installed?
>> >> >
>> >> > > It has 4 GB.
>> >> >
>> >> > That means DMA mapping cannot be the cause of the problem. ?:-(
>> >>
>> >> That isn't entirely true. The BIOS usually allocates a 256 MB ACPI/PCI hole
>> >> that is under the 4GB.
>> >>
>> >> So end up with 3.7 GB, then the 256MB hole, and then right above the 4GB
>> >> you the the remaining memory: 4.3GB.
>> >
>> > How can Pedro find out what physical addresses are in use on his
>> > system?
>>
>> If you have 4GB of RAM then almost certainly you have memory located
>> at addresses over 4GB. If you look at the e820 memory map printed at
>> the start of dmesg on bootup and see entries with addresses of
>> 100000000 or higher reported as usable, then this is the case.
>
> Pedro, can you provide your dmesg output, please? I installed 5GB or RAM
> to my machine now, and even with your .config, I can't see the problem.
>
> Daniel
>
>

There you go Daniel.

Pedro


Attachments:
dmesg2.gz (19.36 kB)

2010-04-12 12:11:17

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 12 April 2010 12:53, Andi Kleen <[email protected]> wrote:
>> Which is exactly what usb_buffer_alloc() does already. So at least for
>> x86 you say this is the right thing to do? However, we don't necessarily
>> need coherent memory on other platforms, which is why I hessitate to
>> enforce that type of memory for all transfer_buffer allocations.
>
> Yes today it's faster at least.
>
> Probably we should have better interfaces for this, but we don't.
>
>>
>> > Or just use GFP_KERNEL and pci_map_* later.
>>
>> The USB core does this already, but at least on Pedro's machine, this
>> seems unsufficient. Unfortunately, I can't reproduce the issue yet, even
>> with more than 4GB of RAM installed.
>
> Then something must be broken in Pedro's system and likely other drivers
> will also not work. I don't think it should be worked around in the USB layer.
>
> -Andi


I'm not putting into question whether something is broken in my
system, but if it is, it must be the ICH9 platform, because I was able
to reproduce it in another laptop.

My laptop is a Lenovo T400 and I was able to reproduce it in a Acer
Aspire 59xx (I don't remember the exact model, but it is one of the
new ones with 15.6 inch - i think they all use the same base). And the
common thing between them is the ICH9 platform.

The only which solved this problem was the first patch sent to me by
Daniel Mack. I've been using it for days straight and it works fine.

Pedro

2010-04-12 12:12:45

by Andi Kleen

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

>
> I'm not putting into question whether something is broken in my
> system, but if it is, it must be the ICH9 platform, because I was able
> to reproduce it in another laptop.
>
> My laptop is a Lenovo T400 and I was able to reproduce it in a Acer
> Aspire 59xx (I don't remember the exact model, but it is one of the
> new ones with 15.6 inch - i think they all use the same base). And the
> common thing between them is the ICH9 platform.

There are lots of systems around with ICH9 that work fine.
I'm typing on one.

>
> The only which solved this problem was the first patch sent to me by
> Daniel Mack. I've been using it for days straight and it works fine.

Can you send a full boot log?

-Andi
--
[email protected] -- Speaking for myself only.

2010-04-12 12:32:46

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 02:12:43PM +0200, Andi Kleen wrote:
> > I'm not putting into question whether something is broken in my
> > system, but if it is, it must be the ICH9 platform, because I was able
> > to reproduce it in another laptop.
> >
> > My laptop is a Lenovo T400 and I was able to reproduce it in a Acer
> > Aspire 59xx (I don't remember the exact model, but it is one of the
> > new ones with 15.6 inch - i think they all use the same base). And the
> > common thing between them is the ICH9 platform.
>
> There are lots of systems around with ICH9 that work fine.
> I'm typing on one.

FWIW, the fix that made it work for Pedro was to use usb_buffer_alloc()
for the transfer_buffer of the audio module.

Another detail I can't explain is that on his machine, the kernel oopses
when kmalloc() with GFP_DMA32 is used. The patch to try this also only
touched the allocation in sound/usb/caiaq/audio.c.

> > The only which solved this problem was the first patch sent to me by
> > Daniel Mack. I've been using it for days straight and it works fine.
>
> Can you send a full boot log?

He just did. I put it online here:

http://caiaq.de/download/tmp/pedro-dmesg

Daniel

2010-04-12 12:47:11

by Andi Kleen

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 02:32:38PM +0200, Daniel Mack wrote:
> Another detail I can't explain is that on his machine, the kernel oopses
> when kmalloc() with GFP_DMA32 is used. The patch to try this also only
> touched the allocation in sound/usb/caiaq/audio.c.

Where did it oops?

>
> > > The only which solved this problem was the first patch sent to me by
> > > Daniel Mack. I've been using it for days straight and it works fine.
> >
> > Can you send a full boot log?
>
> He just did. I put it online here:
>
> http://caiaq.de/download/tmp/pedro-dmesg

The system seems to set up the soft iotlb correctly.

[ 0.468472] PCI-DMA: Using software bounce buffering for IO (SWIOTLB)
[ 0.468539] Placing 64MB software IO TLB between ffff880020000000 - ffff880024000000
[ 0.468610] software IO TLB at phys 0x20000000 - 0x24000000

Also if that was wrong a lot more things would go wrong.

I would suspect the driver. Are you sure:

- it sets up it's dma_masks correctly?
- it uses pci_map_single/sg correctly for all transferred data?

-Andi

--
[email protected] -- Speaking for myself only.

2010-04-12 12:54:31

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 02:47:08PM +0200, Andi Kleen wrote:
> On Mon, Apr 12, 2010 at 02:32:38PM +0200, Daniel Mack wrote:
> > Another detail I can't explain is that on his machine, the kernel oopses
> > when kmalloc() with GFP_DMA32 is used. The patch to try this also only
> > touched the allocation in sound/usb/caiaq/audio.c.
>
> Where did it oops?

Pedro sent me an image:

http://caiaq.de/download/tmp/GFP_DMA32.JPG

The patch I sent him for testing and that lead to this Oops was:

> diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
> index 4328cad..26013be 100644
> --- a/sound/usb/caiaq/audio.c
> +++ b/sound/usb/caiaq/audio.c
> @@ -560,7 +560,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
> ? ? ? ? ? ? ? ?}
>
> ? ? ? ? ? ? ? ?urbs[i]->transfer_buffer =
> - ? ? ? ? ? ? ? ? ? ? ? kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
> + ? ? ? ? ? ? ? ? ? ? ? kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL | GFP_DMA32);
> ? ? ? ? ? ? ? ?if (!urbs[i]->transfer_buffer) {
> ? ? ? ? ? ? ? ? ? ? ? ?log("unable to kmalloc() transfer buffer, OOM!?\n");
> ? ? ? ? ? ? ? ? ? ? ? ?*ret = -ENOMEM;
>


> > http://caiaq.de/download/tmp/pedro-dmesg
>
> The system seems to set up the soft iotlb correctly.
>
> [ 0.468472] PCI-DMA: Using software bounce buffering for IO (SWIOTLB)
> [ 0.468539] Placing 64MB software IO TLB between ffff880020000000 - ffff880024000000
> [ 0.468610] software IO TLB at phys 0x20000000 - 0x24000000
>
> Also if that was wrong a lot more things would go wrong.
>
> I would suspect the driver. Are you sure:
>
> - it sets up it's dma_masks correctly?
> - it uses pci_map_single/sg correctly for all transferred data?

Well, the sound driver itself doesn't care for any of those things, just
like any other USB driver doesn't. The USB core itself of the host
controller driver should do, and as far as I can see, it does that, yes.

Daniel

2010-04-12 15:43:29

by Andi Kleen

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

> > ? ? ? ? ? ? ? ?urbs[i]->transfer_buffer =
> > - ? ? ? ? ? ? ? ? ? ? ? kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
> > + ? ? ? ? ? ? ? ? ? ? ? kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL | GFP_DMA32);

Ah you can't use GFP_DMA32 with kmalloc, only GFP_DMA.

Actually there should be a WARN_ON for this when slab debugging
is enabled.

Slab needs separate caches for dma, and it only has them for GFP_DMA,
but not DMA32. Use __get_free_pages() for GFP_DMA32

> Well, the sound driver itself doesn't care for any of those things, just
> like any other USB driver doesn't. The USB core itself of the host
> controller driver should do, and as far as I can see, it does that, yes.

Hmm, still things must go wrong somewhere. Perhaps need some instrumentation
to see if all the transfer buffers really hit the PCI mapping functions.

It might be interesting to test if the device works with enabled
IOMMU. That would trigger any failures to properly map the buffers
earlier.

-Andi

--
[email protected] -- Speaking for myself only.

2010-04-12 16:17:24

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, 12 Apr 2010, Andi Kleen wrote:

> > Well, the sound driver itself doesn't care for any of those things, just
> > like any other USB driver doesn't. The USB core itself of the host
> > controller driver should do, and as far as I can see, it does that, yes.
>
> Hmm, still things must go wrong somewhere. Perhaps need some instrumentation
> to see if all the transfer buffers really hit the PCI mapping functions.

Such a test has already been carried out earlier in this thread:

http://marc.info/?l=linux-usb&m=127074587029353&w=2
http://marc.info/?l=linux-usb&m=127076841801051&w=2
http://marc.info/?l=linux-usb&m=127082890510415&w=2

> It might be interesting to test if the device works with enabled
> IOMMU. That would trigger any failures to properly map the buffers
> earlier.

Alan Stern

2010-04-12 16:29:50

by Andi Kleen

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 12:17:22PM -0400, Alan Stern wrote:
> On Mon, 12 Apr 2010, Andi Kleen wrote:
>
> > > Well, the sound driver itself doesn't care for any of those things, just
> > > like any other USB driver doesn't. The USB core itself of the host
> > > controller driver should do, and as far as I can see, it does that, yes.
> >
> > Hmm, still things must go wrong somewhere. Perhaps need some instrumentation
> > to see if all the transfer buffers really hit the PCI mapping functions.
>
> Such a test has already been carried out earlier in this thread:
>
> http://marc.info/?l=linux-usb&m=127074587029353&w=2
> http://marc.info/?l=linux-usb&m=127076841801051&w=2
> http://marc.info/?l=linux-usb&m=127082890510415&w=2

Hmm, thanks. But things must still go wrong somewhere, otherwise
the GFP_DMA32 wouldn't be needed?

-Andi

--
[email protected] -- Speaking for myself only.

2010-04-12 16:57:19

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, 12 Apr 2010, Andi Kleen wrote:

> On Mon, Apr 12, 2010 at 12:17:22PM -0400, Alan Stern wrote:
> > On Mon, 12 Apr 2010, Andi Kleen wrote:
> >
> > > > Well, the sound driver itself doesn't care for any of those things, just
> > > > like any other USB driver doesn't. The USB core itself of the host
> > > > controller driver should do, and as far as I can see, it does that, yes.
> > >
> > > Hmm, still things must go wrong somewhere. Perhaps need some instrumentation
> > > to see if all the transfer buffers really hit the PCI mapping functions.
> >
> > Such a test has already been carried out earlier in this thread:
> >
> > http://marc.info/?l=linux-usb&m=127074587029353&w=2
> > http://marc.info/?l=linux-usb&m=127076841801051&w=2
> > http://marc.info/?l=linux-usb&m=127082890510415&w=2
>
> Hmm, thanks. But things must still go wrong somewhere, otherwise
> the GFP_DMA32 wouldn't be needed?

Indeed, something must go wrong somewhere. Since Daniel's patch fixed
the problem by changing the buffer from a streaming mapping to a
coherent mapping, it's logical to assume that bad DMA addresses have
something to do with it. But we don't really know for certain.

Alan Stern

2010-04-12 17:15:16

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 12:57:16PM -0400, Alan Stern wrote:
> On Mon, 12 Apr 2010, Andi Kleen wrote:
> > Hmm, thanks. But things must still go wrong somewhere, otherwise
> > the GFP_DMA32 wouldn't be needed?
>
> Indeed, something must go wrong somewhere. Since Daniel's patch fixed
> the problem by changing the buffer from a streaming mapping to a
> coherent mapping, it's logical to assume that bad DMA addresses have
> something to do with it. But we don't really know for certain.

Given that - at least for non-64-aware host controllers - we want memory
<4GB anyway for USB transfers to avoid DMA bouncing buffers, maybe we
should just do that and fix the problem at this level? I already started
to implement usb_[mz]alloc() and use it in some USB drivers.

But even after all collected wisdom about memory management in this
thread, I'm still uncertain of how to get suitable memory. Using
dma_alloc_coherent() seems overdone as that type of memory is not
necessarily needed and might be a costly good on some platforms. And as
fas as I understand, kmalloc(GFP_DMA) does not avoid memory >4GB.

Can anyone explain which is the right way to go?

Daniel

2010-04-12 17:22:39

by Andi Kleen

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 07:15:07PM +0200, Daniel Mack wrote:
> On Mon, Apr 12, 2010 at 12:57:16PM -0400, Alan Stern wrote:
> > On Mon, 12 Apr 2010, Andi Kleen wrote:
> > > Hmm, thanks. But things must still go wrong somewhere, otherwise
> > > the GFP_DMA32 wouldn't be needed?
> >
> > Indeed, something must go wrong somewhere. Since Daniel's patch fixed
> > the problem by changing the buffer from a streaming mapping to a
> > coherent mapping, it's logical to assume that bad DMA addresses have
> > something to do with it. But we don't really know for certain.
>
> Given that - at least for non-64-aware host controllers - we want memory
> <4GB anyway for USB transfers to avoid DMA bouncing buffers, maybe we
> should just do that and fix the problem at this level? I already started
> to implement usb_[mz]alloc() and use it in some USB drivers.

If the area is not mapped correctly it will fail in other situations,
e.g. with an IOMMU active or in virtualized setups. So the bug
has to be eventually tracked down.

>
> But even after all collected wisdom about memory management in this
> thread, I'm still uncertain of how to get suitable memory. Using
> dma_alloc_coherent() seems overdone as that type of memory is not
> necessarily needed and might be a costly good on some platforms. And as
> fas as I understand, kmalloc(GFP_DMA) does not avoid memory >4GB.

It does actually, but it only has 16MB to play with. Don't use it.
If anything use __get_free_pages(GFP_DMA32), but it's a x86-64
specific code.

> Can anyone explain which is the right way to go?

The right thing would be to define a proper interface for it.

I had an attempt for it a couple of years ago with the mask allocator,
but it didn't make it into the tree.

-Andi
--
[email protected] -- Speaking for myself only.

2010-04-12 17:53:39

by Konrad Rzeszutek Wilk

[permalink] [raw]
Subject: Re: [LKML] Re: USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 07:15:07PM +0200, Daniel Mack wrote:
> On Mon, Apr 12, 2010 at 12:57:16PM -0400, Alan Stern wrote:
> > On Mon, 12 Apr 2010, Andi Kleen wrote:
> > > Hmm, thanks. But things must still go wrong somewhere, otherwise
> > > the GFP_DMA32 wouldn't be needed?
> >
> > Indeed, something must go wrong somewhere. Since Daniel's patch fixed
> > the problem by changing the buffer from a streaming mapping to a
> > coherent mapping, it's logical to assume that bad DMA addresses have
> > something to do with it. But we don't really know for certain.
>
> Given that - at least for non-64-aware host controllers - we want memory
> <4GB anyway for USB transfers to avoid DMA bouncing buffers, maybe we
> should just do that and fix the problem at this level? I already started
> to implement usb_[mz]alloc() and use it in some USB drivers.

You might want to run some benchmarks first to see if it is such a
problem. Keep in mind that you would be addressing only the host-side of
this: all DMA transfers from the USB controller to the memory. But for any
transfer from the user space to the USB device you can't make
the <4GB assumption as the stack/heap in the user-land is stiched from
various memory areas - some of them above your 4GB mark. So when you
write your response to this e-mail, and your /var/spool/clientmqueue is on your
USB disk, the page with your response that is being written to the disk, can be
allocated from a page above the 4GB mark and then has to be bounced-buffered
for the USB controller. Note, I am only talking about 64-bit kernels,
the 32-bit are a different beast altogether when it comes to

Thought please keep in mind that this issue of bounce-buffer is less of
a problem nowadays. Both AMD and Intel are outfitting their machines
with hardware IOMMU's that replace the SWIOTLB (and IBM's high-end boxes
with the Calgary ones). And on AMD the GART has been used for many years
as a poor-man IOMMU.

>
> But even after all collected wisdom about memory management in this
> thread, I'm still uncertain of how to get suitable memory. Using
> dma_alloc_coherent() seems overdone as that type of memory is not
> necessarily needed and might be a costly good on some platforms. And as
> fas as I understand, kmalloc(GFP_DMA) does not avoid memory >4GB.
>
> Can anyone explain which is the right way to go?

Fix whatever makes the DMA address have the wrong value. In the
0x08...00<bus address> address the 0x08 looks quite suspicious. Like it
has been used as a flag or the generated casting code (by GCC) from 64-bit
to 32-bit didn't get the right thing (I remember seeing this with
InfiniBand with RHEL5.. which was GCC 4.1 I think?)

It would be worth instrumenting the PCI-DMA API code and trigger a
dump_stack when that flag (0x008) is detected in the return from the
underlaying page mapping code. If you need help with this I can
give you some debug patches.

2010-04-12 17:56:21

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 07:22:33PM +0200, Andi Kleen wrote:
> On Mon, Apr 12, 2010 at 07:15:07PM +0200, Daniel Mack wrote:
> > Given that - at least for non-64-aware host controllers - we want memory
> > <4GB anyway for USB transfers to avoid DMA bouncing buffers, maybe we
> > should just do that and fix the problem at this level? I already started
> > to implement usb_[mz]alloc() and use it in some USB drivers.
>
> If the area is not mapped correctly it will fail in other situations,
> e.g. with an IOMMU active or in virtualized setups. So the bug
> has to be eventually tracked down.

Ok, agreed. But we all agree to the fact that we need an interface for
such allocations to avoid bounce buffers? If that is the case, we could
already start to implement that while we're tracking down the actual
bug.

[...]

> > Can anyone explain which is the right way to go?
>
> The right thing would be to define a proper interface for it.
>
> I had an attempt for it a couple of years ago with the mask allocator,
> but it didn't make it into the tree.

Any plans to continue on this? Or can you dig it out again so others can
pick up the idea?

Daniel

2010-04-12 18:56:53

by Sarah Sharp

[permalink] [raw]
Subject: Re: [alsa-devel] USB transfer_buffer allocations on 64bit systems

On Sat, Apr 10, 2010 at 11:02:53AM -0600, Robert Hancock wrote:
> On Sat, Apr 10, 2010 at 2:34 AM, Daniel Mack <[email protected]> wrote:
> > On Fri, Apr 09, 2010 at 05:38:13PM -0600, Robert Hancock wrote:
> >> On Fri, Apr 9, 2010 at 10:50 AM, Sarah Sharp
> >> <[email protected]> wrote:
> >> > What makes you think that? ?I've seen URB buffers with 64-bit DMA
> >> > addresses. ?I can tell when the debug polling loop runs and I look at
> >> > the DMA addresses the xHCI driver is feeding to the hardware:
> >> >
> >> > Dev 1 endpoint ring 0:
> >> > xhci_hcd 0000:05:00.0: @71a49800 01000680 00080000 00000008 00000841
> >> >
> >> > So the TRB at address 71a49800 is pointing to a buffer at address
> >> > 0x0008000001000680.
> >>
> >> I'm not sure why the address would be that huge, unless it's not
> >> actually a physical address, or there's some kind of remapping going
> >> on?
> >>
> >> >
> >> > If I'm setting a DMA mask wrong somewhere, or doing something else to
> >> > limit the DMA to 32-bit, then please let me know.
> >>
> >> The DMA mask for the controller isn't being set anywhere (in the
> >> version that's in Linus' current git anyway). In that case it'll
> >> default to 32-bit and any DMA mappings above 4GB will need to be
> >> remapped. The controller driver doesn't do the mapping itself but the
> >> USB core does, passing in the controller device as the one doing the
> >> DMA, so if the controller's DMA mask is set to 32-bit then the buffers
> >> passed in will get remapped/bounced accordingly.
> >
> > So if we're seeing physical addresses in the log above, and the xHCI
> > driver does not explicitly allow the USB core to use addresses above
> > 4GB, why shouldn't the same thing be true as well for EHCI?
> > (Which would then be exactly the case we're seeing)
>
> That is a bit suspicious, yes. With the DMA mask at default I don't
> expect that should happen. Sarah, what kind of traffic was happening
> when you saw that (bulk, isochronous, etc)?

Ring 0 is the default control ring, so it must be control transfers.
That's the first control transfer on the ring (and it didn't fill), so
it must have come from the USB core.

I was running the USB mass storage driver, and the bulk endpoint rings
don't have the high 32-bits of the address set. It mostly uses the
scatter-gather interface, which calls usb_buffer_map_sg(), so that's not
surprising.

Sarah Sharp

2010-04-12 20:39:07

by Robert Hancock

[permalink] [raw]
Subject: Re: [alsa-devel] USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 12:56 PM, Sarah Sharp
<[email protected]> wrote:
> On Sat, Apr 10, 2010 at 11:02:53AM -0600, Robert Hancock wrote:
>> On Sat, Apr 10, 2010 at 2:34 AM, Daniel Mack <[email protected]> wrote:
>> > On Fri, Apr 09, 2010 at 05:38:13PM -0600, Robert Hancock wrote:
>> >> On Fri, Apr 9, 2010 at 10:50 AM, Sarah Sharp
>> >> <[email protected]> wrote:
>> >> > What makes you think that? ?I've seen URB buffers with 64-bit DMA
>> >> > addresses. ?I can tell when the debug polling loop runs and I look at
>> >> > the DMA addresses the xHCI driver is feeding to the hardware:
>> >> >
>> >> > Dev 1 endpoint ring 0:
>> >> > xhci_hcd 0000:05:00.0: @71a49800 01000680 00080000 00000008 00000841
>> >> >
>> >> > So the TRB at address 71a49800 is pointing to a buffer at address
>> >> > 0x0008000001000680.
>> >>
>> >> I'm not sure why the address would be that huge, unless it's not
>> >> actually a physical address, or there's some kind of remapping going
>> >> on?
>> >>
>> >> >
>> >> > If I'm setting a DMA mask wrong somewhere, or doing something else to
>> >> > limit the DMA to 32-bit, then please let me know.
>> >>
>> >> The DMA mask for the controller isn't being set anywhere (in the
>> >> version that's in Linus' current git anyway). In that case it'll
>> >> default to 32-bit and any DMA mappings above 4GB will need to be
>> >> remapped. The controller driver doesn't do the mapping itself but the
>> >> USB core does, passing in the controller device as the one doing the
>> >> DMA, so if the controller's DMA mask is set to 32-bit then the buffers
>> >> passed in will get remapped/bounced accordingly.
>> >
>> > So if we're seeing physical addresses in the log above, and the xHCI
>> > driver does not explicitly allow the USB core to use addresses above
>> > 4GB, why shouldn't the same thing be true as well for EHCI?
>> > (Which would then be exactly the case we're seeing)
>>
>> That is a bit suspicious, yes. With the DMA mask at default I don't
>> expect that should happen. Sarah, what kind of traffic was happening
>> when you saw that (bulk, isochronous, etc)?
>
> Ring 0 is the default control ring, so it must be control transfers.
> That's the first control transfer on the ring (and it didn't fill), so
> it must have come from the USB core.
>
> I was running the USB mass storage driver, and the bulk endpoint rings
> don't have the high 32-bits of the address set. ?It mostly uses the
> scatter-gather interface, which calls usb_buffer_map_sg(), so that's not
> surprising.

Is this machine using an IOMMU or something which would be remapping
physical addresses? That address 0x0008000001000680 seems huge, I
don't see how it could even be a valid bus address otherwise..

2010-04-12 20:59:09

by Sarah Sharp

[permalink] [raw]
Subject: Re: [alsa-devel] USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 02:39:04PM -0600, Robert Hancock wrote:
> On Mon, Apr 12, 2010 at 12:56 PM, Sarah Sharp
> <[email protected]> wrote:
> > On Sat, Apr 10, 2010 at 11:02:53AM -0600, Robert Hancock wrote:
> >> On Sat, Apr 10, 2010 at 2:34 AM, Daniel Mack <[email protected]> wrote:
> >> > On Fri, Apr 09, 2010 at 05:38:13PM -0600, Robert Hancock wrote:
> >> >> On Fri, Apr 9, 2010 at 10:50 AM, Sarah Sharp
> >> >> <[email protected]> wrote:
> >> >> > What makes you think that? ?I've seen URB buffers with 64-bit DMA
> >> >> > addresses. ?I can tell when the debug polling loop runs and I look at
> >> >> > the DMA addresses the xHCI driver is feeding to the hardware:
> >> >> >
> >> >> > Dev 1 endpoint ring 0:
> >> >> > xhci_hcd 0000:05:00.0: @71a49800 01000680 00080000 00000008 00000841
> >> >> >
> >> >> > So the TRB at address 71a49800 is pointing to a buffer at address
> >> >> > 0x0008000001000680.
> >> >>
> >> >> I'm not sure why the address would be that huge, unless it's not
> >> >> actually a physical address, or there's some kind of remapping going
> >> >> on?
> >> >>
> >> >> >
> >> >> > If I'm setting a DMA mask wrong somewhere, or doing something else to
> >> >> > limit the DMA to 32-bit, then please let me know.
> >> >>
> >> >> The DMA mask for the controller isn't being set anywhere (in the
> >> >> version that's in Linus' current git anyway). In that case it'll
> >> >> default to 32-bit and any DMA mappings above 4GB will need to be
> >> >> remapped. The controller driver doesn't do the mapping itself but the
> >> >> USB core does, passing in the controller device as the one doing the
> >> >> DMA, so if the controller's DMA mask is set to 32-bit then the buffers
> >> >> passed in will get remapped/bounced accordingly.
> >> >
> >> > So if we're seeing physical addresses in the log above, and the xHCI
> >> > driver does not explicitly allow the USB core to use addresses above
> >> > 4GB, why shouldn't the same thing be true as well for EHCI?
> >> > (Which would then be exactly the case we're seeing)
> >>
> >> That is a bit suspicious, yes. With the DMA mask at default I don't
> >> expect that should happen. Sarah, what kind of traffic was happening
> >> when you saw that (bulk, isochronous, etc)?
> >
> > Ring 0 is the default control ring, so it must be control transfers.
> > That's the first control transfer on the ring (and it didn't fill), so
> > it must have come from the USB core.
> >
> > I was running the USB mass storage driver, and the bulk endpoint rings
> > don't have the high 32-bits of the address set. ?It mostly uses the
> > scatter-gather interface, which calls usb_buffer_map_sg(), so that's not
> > surprising.
>
> Is this machine using an IOMMU or something which would be remapping
> physical addresses? That address 0x0008000001000680 seems huge, I
> don't see how it could even be a valid bus address otherwise..

Oh, shoot, nevermind. That TRB has a slightly different format, where
the setup data for the control transfer is substituted for the DMA
buffer address. I'll have to look through my logs to see if there's any
real 64-bit DMA addresses in there, and fix xHCI's DMA mask.

Sarah Sharp

2010-04-13 18:16:48

by Daniel Mack

[permalink] [raw]
Subject: Re: [PATCH] USB: rename usb_buffer_alloc() and usb_buffer_free()

On Mon, Apr 12, 2010 at 01:17:25PM +0200, Daniel Mack wrote:
> For more clearance what the functions actually do,
>
> usb_buffer_alloc() is renamed to usb_alloc_coherent()
> usb_buffer_free() is renamed to usb_free_coherent()
>
> They should only be used in code which really needs DMA coherency.
>
> All call sites have been changed accordingly, except for staging
> drivers.

Is this ok? As it's quite big, I think it should be merged soon if there
are no objections.

Thanks,
Daniel


> Signed-off-by: Daniel Mack <[email protected]>
> Cc: Alan Stern <[email protected]>
> Cc: Greg KH <[email protected]>
> Cc: Pedro Ribeiro <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> Documentation/DocBook/writing_usb_driver.tmpl | 2 +-
> Documentation/usb/dma.txt | 4 +-
> drivers/hid/usbhid/hid-core.c | 16 +++++-----
> drivers/hid/usbhid/usbkbd.c | 12 ++++----
> drivers/hid/usbhid/usbmouse.c | 6 ++--
> drivers/input/joystick/xpad.c | 16 +++++-----
> drivers/input/misc/ati_remote.c | 12 ++++----
> drivers/input/misc/ati_remote2.c | 4 +-
> drivers/input/misc/cm109.c | 24 +++++++-------
> drivers/input/misc/keyspan_remote.c | 6 ++--
> drivers/input/misc/powermate.c | 16 +++++-----
> drivers/input/misc/yealink.c | 24 +++++++-------
> drivers/input/mouse/appletouch.c | 12 ++++----
> drivers/input/mouse/bcm5974.c | 24 +++++++-------
> drivers/input/tablet/acecad.c | 6 ++--
> drivers/input/tablet/aiptek.c | 14 ++++----
> drivers/input/tablet/gtco.c | 12 ++++----
> drivers/input/tablet/kbtab.c | 6 ++--
> drivers/input/tablet/wacom_sys.c | 10 +++---
> drivers/input/touchscreen/usbtouchscreen.c | 8 ++--
> drivers/media/dvb/dvb-usb/usb-urb.c | 7 ++--
> drivers/media/dvb/ttusb-dec/ttusb_dec.c | 6 ++--
> drivers/media/video/au0828/au0828-video.c | 4 +-
> drivers/media/video/cx231xx/cx231xx-core.c | 14 ++++----
> drivers/media/video/em28xx/em28xx-core.c | 4 +-
> drivers/media/video/gspca/benq.c | 4 +-
> drivers/media/video/gspca/gspca.c | 30 +++++++++---------
> drivers/media/video/hdpvr/hdpvr-video.c | 8 ++--
> drivers/media/video/tlg2300/pd-video.c | 14 ++++----
> drivers/media/video/usbvision/usbvision-core.c | 16 +++++-----
> drivers/media/video/uvc/uvc_video.c | 4 +-
> drivers/net/can/usb/ems_usb.c | 18 +++++-----
> drivers/net/usb/kaweth.c | 12 ++++----
> drivers/net/wireless/ath/ar9170/usb.c | 8 ++--
> drivers/net/wireless/zd1211rw/zd_usb.c | 10 +++---
> drivers/usb/class/cdc-acm.c | 22 +++++++-------
> drivers/usb/class/cdc-wdm.c | 38 ++++++++++++------------
> drivers/usb/class/usblp.c | 2 +-
> drivers/usb/core/usb.c | 20 ++++++------
> drivers/usb/misc/appledisplay.c | 6 ++--
> drivers/usb/misc/ftdi-elan.c | 18 +++++-----
> drivers/usb/misc/iowarrior.c | 12 ++++----
> drivers/usb/misc/usblcd.c | 8 ++--
> drivers/usb/misc/usbtest.c | 16 +++++-----
> drivers/usb/storage/onetouch.c | 12 ++++----
> drivers/usb/storage/usb.c | 12 ++++----
> drivers/usb/usb-skeleton.c | 10 +++---
> drivers/watchdog/pcwd_usb.c | 6 ++--
> include/linux/usb.h | 6 ++--
> sound/usb/midi.c | 14 ++++----
> sound/usb/misc/ua101.c | 16 +++++-----
> sound/usb/urb.c | 18 +++++-----
> 52 files changed, 315 insertions(+), 314 deletions(-)
>
> diff --git a/Documentation/DocBook/writing_usb_driver.tmpl b/Documentation/DocBook/writing_usb_driver.tmpl
> index eeff19c..bd97a13 100644
> --- a/Documentation/DocBook/writing_usb_driver.tmpl
> +++ b/Documentation/DocBook/writing_usb_driver.tmpl
> @@ -342,7 +342,7 @@ static inline void skel_delete (struct usb_skel *dev)
> {
> kfree (dev->bulk_in_buffer);
> if (dev->bulk_out_buffer != NULL)
> - usb_buffer_free (dev->udev, dev->bulk_out_size,
> + usb_free_coherent (dev->udev, dev->bulk_out_size,
> dev->bulk_out_buffer,
> dev->write_urb->transfer_dma);
> usb_free_urb (dev->write_urb);
> diff --git a/Documentation/usb/dma.txt b/Documentation/usb/dma.txt
> index cfdcd16..a37e59c 100644
> --- a/Documentation/usb/dma.txt
> +++ b/Documentation/usb/dma.txt
> @@ -43,10 +43,10 @@ and effects like cache-trashing can impose subtle penalties.
> kind of addresses to store in urb->transfer_buffer and urb->transfer_dma.
> You'd also set URB_NO_TRANSFER_DMA_MAP in urb->transfer_flags:
>
> - void *usb_buffer_alloc (struct usb_device *dev, size_t size,
> + void *usb_alloc_coherent (struct usb_device *dev, size_t size,
> int mem_flags, dma_addr_t *dma);
>
> - void usb_buffer_free (struct usb_device *dev, size_t size,
> + void usb_free_coherent (struct usb_device *dev, size_t size,
> void *addr, dma_addr_t dma);
>
> Most drivers should *NOT* be using these primitives; they don't need
> diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
> index 56d06cd..8496f3a 100644
> --- a/drivers/hid/usbhid/hid-core.c
> +++ b/drivers/hid/usbhid/hid-core.c
> @@ -783,13 +783,13 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
> {
> struct usbhid_device *usbhid = hid->driver_data;
>
> - usbhid->inbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_KERNEL,
> + usbhid->inbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
> &usbhid->inbuf_dma);
> - usbhid->outbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_KERNEL,
> + usbhid->outbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
> &usbhid->outbuf_dma);
> - usbhid->cr = usb_buffer_alloc(dev, sizeof(*usbhid->cr), GFP_KERNEL,
> + usbhid->cr = usb_alloc_coherent(dev, sizeof(*usbhid->cr), GFP_KERNEL,
> &usbhid->cr_dma);
> - usbhid->ctrlbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_KERNEL,
> + usbhid->ctrlbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
> &usbhid->ctrlbuf_dma);
> if (!usbhid->inbuf || !usbhid->outbuf || !usbhid->cr ||
> !usbhid->ctrlbuf)
> @@ -844,10 +844,10 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
> {
> struct usbhid_device *usbhid = hid->driver_data;
>
> - usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
> - usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
> - usb_buffer_free(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma);
> - usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
> + usb_free_coherent(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
> + usb_free_coherent(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
> + usb_free_coherent(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma);
> + usb_free_coherent(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
> }
>
> static int usbhid_parse(struct hid_device *hid)
> diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
> index f843443..b86f866 100644
> --- a/drivers/hid/usbhid/usbkbd.c
> +++ b/drivers/hid/usbhid/usbkbd.c
> @@ -197,11 +197,11 @@ static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
> return -1;
> if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL)))
> return -1;
> - if (!(kbd->new = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
> + if (!(kbd->new = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
> return -1;
> - if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), GFP_ATOMIC, &kbd->cr_dma)))
> + if (!(kbd->cr = usb_alloc_coherent(dev, sizeof(struct usb_ctrlrequest), GFP_ATOMIC, &kbd->cr_dma)))
> return -1;
> - if (!(kbd->leds = usb_buffer_alloc(dev, 1, GFP_ATOMIC, &kbd->leds_dma)))
> + if (!(kbd->leds = usb_alloc_coherent(dev, 1, GFP_ATOMIC, &kbd->leds_dma)))
> return -1;
>
> return 0;
> @@ -211,9 +211,9 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
> {
> usb_free_urb(kbd->irq);
> usb_free_urb(kbd->led);
> - usb_buffer_free(dev, 8, kbd->new, kbd->new_dma);
> - usb_buffer_free(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma);
> - usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma);
> + usb_free_coherent(dev, 8, kbd->new, kbd->new_dma);
> + usb_free_coherent(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma);
> + usb_free_coherent(dev, 1, kbd->leds, kbd->leds_dma);
> }
>
> static int usb_kbd_probe(struct usb_interface *iface,
> diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c
> index 72ab4b2..79b2bf8 100644
> --- a/drivers/hid/usbhid/usbmouse.c
> +++ b/drivers/hid/usbhid/usbmouse.c
> @@ -142,7 +142,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
> if (!mouse || !input_dev)
> goto fail1;
>
> - mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma);
> + mouse->data = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &mouse->data_dma);
> if (!mouse->data)
> goto fail1;
>
> @@ -205,7 +205,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
> fail3:
> usb_free_urb(mouse->irq);
> fail2:
> - usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
> + usb_free_coherent(dev, 8, mouse->data, mouse->data_dma);
> fail1:
> input_free_device(input_dev);
> kfree(mouse);
> @@ -221,7 +221,7 @@ static void usb_mouse_disconnect(struct usb_interface *intf)
> usb_kill_urb(mouse->irq);
> input_unregister_device(mouse->dev);
> usb_free_urb(mouse->irq);
> - usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
> + usb_free_coherent(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
> kfree(mouse);
> }
> }
> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
> index 9b3353b..c1087ce 100644
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
> @@ -533,8 +533,8 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
> if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
> return 0;
>
> - xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN,
> - GFP_KERNEL, &xpad->odata_dma);
> + xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
> + GFP_KERNEL, &xpad->odata_dma);
> if (!xpad->odata)
> goto fail1;
>
> @@ -554,7 +554,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
>
> return 0;
>
> - fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
> + fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
> fail1: return error;
> }
>
> @@ -568,7 +568,7 @@ static void xpad_deinit_output(struct usb_xpad *xpad)
> {
> if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) {
> usb_free_urb(xpad->irq_out);
> - usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
> + usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
> xpad->odata, xpad->odata_dma);
> }
> }
> @@ -788,8 +788,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
> if (!xpad || !input_dev)
> goto fail1;
>
> - xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
> - GFP_KERNEL, &xpad->idata_dma);
> + xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
> + GFP_KERNEL, &xpad->idata_dma);
> if (!xpad->idata)
> goto fail1;
>
> @@ -942,7 +942,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
> fail5: usb_kill_urb(xpad->irq_in);
> fail4: usb_free_urb(xpad->irq_in);
> fail3: xpad_deinit_output(xpad);
> - fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
> + fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
> fail1: input_free_device(input_dev);
> kfree(xpad);
> return error;
> @@ -964,7 +964,7 @@ static void xpad_disconnect(struct usb_interface *intf)
> usb_kill_urb(xpad->irq_in);
> }
> usb_free_urb(xpad->irq_in);
> - usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
> + usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
> xpad->idata, xpad->idata_dma);
> kfree(xpad);
> }
> diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c
> index 614b65d..2b9a2c8 100644
> --- a/drivers/input/misc/ati_remote.c
> +++ b/drivers/input/misc/ati_remote.c
> @@ -620,13 +620,13 @@ static void ati_remote_irq_in(struct urb *urb)
> static int ati_remote_alloc_buffers(struct usb_device *udev,
> struct ati_remote *ati_remote)
> {
> - ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC,
> - &ati_remote->inbuf_dma);
> + ati_remote->inbuf = usb_alloc_coherent(udev, DATA_BUFSIZE, GFP_ATOMIC,
> + &ati_remote->inbuf_dma);
> if (!ati_remote->inbuf)
> return -1;
>
> - ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC,
> - &ati_remote->outbuf_dma);
> + ati_remote->outbuf = usb_alloc_coherent(udev, DATA_BUFSIZE, GFP_ATOMIC,
> + &ati_remote->outbuf_dma);
> if (!ati_remote->outbuf)
> return -1;
>
> @@ -649,10 +649,10 @@ static void ati_remote_free_buffers(struct ati_remote *ati_remote)
> usb_free_urb(ati_remote->irq_urb);
> usb_free_urb(ati_remote->out_urb);
>
> - usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
> + usb_free_coherent(ati_remote->udev, DATA_BUFSIZE,
> ati_remote->inbuf, ati_remote->inbuf_dma);
>
> - usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
> + usb_free_coherent(ati_remote->udev, DATA_BUFSIZE,
> ati_remote->outbuf, ati_remote->outbuf_dma);
> }
>
> diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
> index 2124b99..e148749 100644
> --- a/drivers/input/misc/ati_remote2.c
> +++ b/drivers/input/misc/ati_remote2.c
> @@ -589,7 +589,7 @@ static int ati_remote2_urb_init(struct ati_remote2 *ar2)
> int i, pipe, maxp;
>
> for (i = 0; i < 2; i++) {
> - ar2->buf[i] = usb_buffer_alloc(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]);
> + ar2->buf[i] = usb_alloc_coherent(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]);
> if (!ar2->buf[i])
> return -ENOMEM;
>
> @@ -617,7 +617,7 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
>
> for (i = 0; i < 2; i++) {
> usb_free_urb(ar2->urb[i]);
> - usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
> + usb_free_coherent(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
> }
> }
>
> diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c
> index 86457fe..635b7ac 100644
> --- a/drivers/input/misc/cm109.c
> +++ b/drivers/input/misc/cm109.c
> @@ -630,14 +630,14 @@ static const struct usb_device_id cm109_usb_table[] = {
> static void cm109_usb_cleanup(struct cm109_dev *dev)
> {
> if (dev->ctl_req)
> - usb_buffer_free(dev->udev, sizeof(*(dev->ctl_req)),
> - dev->ctl_req, dev->ctl_req_dma);
> + usb_free_coherent(dev->udev, sizeof(*(dev->ctl_req)),
> + dev->ctl_req, dev->ctl_req_dma);
> if (dev->ctl_data)
> - usb_buffer_free(dev->udev, USB_PKT_LEN,
> - dev->ctl_data, dev->ctl_dma);
> + usb_free_coherent(dev->udev, USB_PKT_LEN,
> + dev->ctl_data, dev->ctl_dma);
> if (dev->irq_data)
> - usb_buffer_free(dev->udev, USB_PKT_LEN,
> - dev->irq_data, dev->irq_dma);
> + usb_free_coherent(dev->udev, USB_PKT_LEN,
> + dev->irq_data, dev->irq_dma);
>
> usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */
> usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */
> @@ -686,18 +686,18 @@ static int cm109_usb_probe(struct usb_interface *intf,
> goto err_out;
>
> /* allocate usb buffers */
> - dev->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
> - GFP_KERNEL, &dev->irq_dma);
> + dev->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN,
> + GFP_KERNEL, &dev->irq_dma);
> if (!dev->irq_data)
> goto err_out;
>
> - dev->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
> - GFP_KERNEL, &dev->ctl_dma);
> + dev->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN,
> + GFP_KERNEL, &dev->ctl_dma);
> if (!dev->ctl_data)
> goto err_out;
>
> - dev->ctl_req = usb_buffer_alloc(udev, sizeof(*(dev->ctl_req)),
> - GFP_KERNEL, &dev->ctl_req_dma);
> + dev->ctl_req = usb_alloc_coherent(udev, sizeof(*(dev->ctl_req)),
> + GFP_KERNEL, &dev->ctl_req_dma);
> if (!dev->ctl_req)
> goto err_out;
>
> diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c
> index 86afdd1..a93c525 100644
> --- a/drivers/input/misc/keyspan_remote.c
> +++ b/drivers/input/misc/keyspan_remote.c
> @@ -464,7 +464,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
> remote->in_endpoint = endpoint;
> remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */
>
> - remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma);
> + remote->in_buffer = usb_alloc_coherent(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma);
> if (!remote->in_buffer) {
> error = -ENOMEM;
> goto fail1;
> @@ -543,7 +543,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
> return 0;
>
> fail3: usb_free_urb(remote->irq_urb);
> - fail2: usb_buffer_free(udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
> + fail2: usb_free_coherent(udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
> fail1: kfree(remote);
> input_free_device(input_dev);
>
> @@ -564,7 +564,7 @@ static void keyspan_disconnect(struct usb_interface *interface)
> input_unregister_device(remote->input);
> usb_kill_urb(remote->irq_urb);
> usb_free_urb(remote->irq_urb);
> - usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
> + usb_free_coherent(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
> kfree(remote);
> }
> }
> diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c
> index 668913d..a0b00d6 100644
> --- a/drivers/input/misc/powermate.c
> +++ b/drivers/input/misc/powermate.c
> @@ -276,13 +276,13 @@ static int powermate_input_event(struct input_dev *dev, unsigned int type, unsig
>
> static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm)
> {
> - pm->data = usb_buffer_alloc(udev, POWERMATE_PAYLOAD_SIZE_MAX,
> - GFP_ATOMIC, &pm->data_dma);
> + pm->data = usb_alloc_coherent(udev, POWERMATE_PAYLOAD_SIZE_MAX,
> + GFP_ATOMIC, &pm->data_dma);
> if (!pm->data)
> return -1;
>
> - pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)),
> - GFP_ATOMIC, &pm->configcr_dma);
> + pm->configcr = usb_alloc_coherent(udev, sizeof(*(pm->configcr)),
> + GFP_ATOMIC, &pm->configcr_dma);
> if (!pm->configcr)
> return -1;
>
> @@ -291,10 +291,10 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev
>
> static void powermate_free_buffers(struct usb_device *udev, struct powermate_device *pm)
> {
> - usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX,
> - pm->data, pm->data_dma);
> - usb_buffer_free(udev, sizeof(*(pm->configcr)),
> - pm->configcr, pm->configcr_dma);
> + usb_free_coherent(udev, POWERMATE_PAYLOAD_SIZE_MAX,
> + pm->data, pm->data_dma);
> + usb_free_coherent(udev, sizeof(*(pm->configcr)),
> + pm->configcr, pm->configcr_dma);
> }
>
> /* Called whenever a USB device matching one in our supported devices table is connected */
> diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
> index 93a22ac..f584985 100644
> --- a/drivers/input/misc/yealink.c
> +++ b/drivers/input/misc/yealink.c
> @@ -836,12 +836,12 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
> usb_free_urb(yld->urb_irq);
> usb_free_urb(yld->urb_ctl);
>
> - usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
> - yld->ctl_req, yld->ctl_req_dma);
> - usb_buffer_free(yld->udev, USB_PKT_LEN,
> - yld->ctl_data, yld->ctl_dma);
> - usb_buffer_free(yld->udev, USB_PKT_LEN,
> - yld->irq_data, yld->irq_dma);
> + usb_free_coherent(yld->udev, sizeof(*(yld->ctl_req)),
> + yld->ctl_req, yld->ctl_req_dma);
> + usb_free_coherent(yld->udev, USB_PKT_LEN,
> + yld->ctl_data, yld->ctl_dma);
> + usb_free_coherent(yld->udev, USB_PKT_LEN,
> + yld->irq_data, yld->irq_dma);
>
> kfree(yld);
> return err;
> @@ -886,18 +886,18 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
> return usb_cleanup(yld, -ENOMEM);
>
> /* allocate usb buffers */
> - yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
> - GFP_ATOMIC, &yld->irq_dma);
> + yld->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN,
> + GFP_ATOMIC, &yld->irq_dma);
> if (yld->irq_data == NULL)
> return usb_cleanup(yld, -ENOMEM);
>
> - yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
> - GFP_ATOMIC, &yld->ctl_dma);
> + yld->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN,
> + GFP_ATOMIC, &yld->ctl_dma);
> if (!yld->ctl_data)
> return usb_cleanup(yld, -ENOMEM);
>
> - yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)),
> - GFP_ATOMIC, &yld->ctl_req_dma);
> + yld->ctl_req = usb_alloc_coherent(udev, sizeof(*(yld->ctl_req)),
> + GFP_ATOMIC, &yld->ctl_req_dma);
> if (yld->ctl_req == NULL)
> return usb_cleanup(yld, -ENOMEM);
>
> diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
> index 53ec7dd..05edd75 100644
> --- a/drivers/input/mouse/appletouch.c
> +++ b/drivers/input/mouse/appletouch.c
> @@ -806,8 +806,8 @@ static int atp_probe(struct usb_interface *iface,
> if (!dev->urb)
> goto err_free_devs;
>
> - dev->data = usb_buffer_alloc(dev->udev, dev->info->datalen, GFP_KERNEL,
> - &dev->urb->transfer_dma);
> + dev->data = usb_alloc_coherent(dev->udev, dev->info->datalen, GFP_KERNEL,
> + &dev->urb->transfer_dma);
> if (!dev->data)
> goto err_free_urb;
>
> @@ -862,8 +862,8 @@ static int atp_probe(struct usb_interface *iface,
> return 0;
>
> err_free_buffer:
> - usb_buffer_free(dev->udev, dev->info->datalen,
> - dev->data, dev->urb->transfer_dma);
> + usb_free_coherent(dev->udev, dev->info->datalen,
> + dev->data, dev->urb->transfer_dma);
> err_free_urb:
> usb_free_urb(dev->urb);
> err_free_devs:
> @@ -881,8 +881,8 @@ static void atp_disconnect(struct usb_interface *iface)
> if (dev) {
> usb_kill_urb(dev->urb);
> input_unregister_device(dev->input);
> - usb_buffer_free(dev->udev, dev->info->datalen,
> - dev->data, dev->urb->transfer_dma);
> + usb_free_coherent(dev->udev, dev->info->datalen,
> + dev->data, dev->urb->transfer_dma);
> usb_free_urb(dev->urb);
> kfree(dev);
> }
> diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
> index 4f8fe08..aa3359a 100644
> --- a/drivers/input/mouse/bcm5974.c
> +++ b/drivers/input/mouse/bcm5974.c
> @@ -715,15 +715,15 @@ static int bcm5974_probe(struct usb_interface *iface,
> if (!dev->tp_urb)
> goto err_free_bt_urb;
>
> - dev->bt_data = usb_buffer_alloc(dev->udev,
> - dev->cfg.bt_datalen, GFP_KERNEL,
> - &dev->bt_urb->transfer_dma);
> + dev->bt_data = usb_alloc_coherent(dev->udev,
> + dev->cfg.bt_datalen, GFP_KERNEL,
> + &dev->bt_urb->transfer_dma);
> if (!dev->bt_data)
> goto err_free_urb;
>
> - dev->tp_data = usb_buffer_alloc(dev->udev,
> - dev->cfg.tp_datalen, GFP_KERNEL,
> - &dev->tp_urb->transfer_dma);
> + dev->tp_data = usb_alloc_coherent(dev->udev,
> + dev->cfg.tp_datalen, GFP_KERNEL,
> + &dev->tp_urb->transfer_dma);
> if (!dev->tp_data)
> goto err_free_bt_buffer;
>
> @@ -765,10 +765,10 @@ static int bcm5974_probe(struct usb_interface *iface,
> return 0;
>
> err_free_buffer:
> - usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
> + usb_free_coherent(dev->udev, dev->cfg.tp_datalen,
> dev->tp_data, dev->tp_urb->transfer_dma);
> err_free_bt_buffer:
> - usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
> + usb_free_coherent(dev->udev, dev->cfg.bt_datalen,
> dev->bt_data, dev->bt_urb->transfer_dma);
> err_free_urb:
> usb_free_urb(dev->tp_urb);
> @@ -788,10 +788,10 @@ static void bcm5974_disconnect(struct usb_interface *iface)
> usb_set_intfdata(iface, NULL);
>
> input_unregister_device(dev->input);
> - usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
> - dev->tp_data, dev->tp_urb->transfer_dma);
> - usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
> - dev->bt_data, dev->bt_urb->transfer_dma);
> + usb_free_coherent(dev->udev, dev->cfg.tp_datalen,
> + dev->tp_data, dev->tp_urb->transfer_dma);
> + usb_free_coherent(dev->udev, dev->cfg.bt_datalen,
> + dev->bt_data, dev->bt_urb->transfer_dma);
> usb_free_urb(dev->tp_urb);
> usb_free_urb(dev->bt_urb);
> kfree(dev);
> diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c
> index 670c61c..c047016 100644
> --- a/drivers/input/tablet/acecad.c
> +++ b/drivers/input/tablet/acecad.c
> @@ -155,7 +155,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
> goto fail1;
> }
>
> - acecad->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &acecad->data_dma);
> + acecad->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &acecad->data_dma);
> if (!acecad->data) {
> err= -ENOMEM;
> goto fail1;
> @@ -241,7 +241,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
>
> return 0;
>
> - fail2: usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
> + fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma);
> fail1: input_free_device(input_dev);
> kfree(acecad);
> return err;
> @@ -256,7 +256,7 @@ static void usb_acecad_disconnect(struct usb_interface *intf)
> usb_kill_urb(acecad->irq);
> input_unregister_device(acecad->input);
> usb_free_urb(acecad->irq);
> - usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
> + usb_free_coherent(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
> kfree(acecad);
> }
> }
> diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
> index 4be039d..51b80b0 100644
> --- a/drivers/input/tablet/aiptek.c
> +++ b/drivers/input/tablet/aiptek.c
> @@ -1711,8 +1711,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
> goto fail1;
> }
>
> - aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
> - GFP_ATOMIC, &aiptek->data_dma);
> + aiptek->data = usb_alloc_coherent(usbdev, AIPTEK_PACKET_LENGTH,
> + GFP_ATOMIC, &aiptek->data_dma);
> if (!aiptek->data) {
> dev_warn(&intf->dev, "cannot allocate usb buffer\n");
> goto fail1;
> @@ -1884,8 +1884,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
>
> fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
> fail3: usb_free_urb(aiptek->urb);
> - fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
> - aiptek->data_dma);
> + fail2: usb_free_coherent(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
> + aiptek->data_dma);
> fail1: usb_set_intfdata(intf, NULL);
> input_free_device(inputdev);
> kfree(aiptek);
> @@ -1909,9 +1909,9 @@ static void aiptek_disconnect(struct usb_interface *intf)
> input_unregister_device(aiptek->inputdev);
> sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
> usb_free_urb(aiptek->urb);
> - usb_buffer_free(interface_to_usbdev(intf),
> - AIPTEK_PACKET_LENGTH,
> - aiptek->data, aiptek->data_dma);
> + usb_free_coherent(interface_to_usbdev(intf),
> + AIPTEK_PACKET_LENGTH,
> + aiptek->data, aiptek->data_dma);
> kfree(aiptek);
> }
> }
> diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
> index 866a9ee..8ea6afe 100644
> --- a/drivers/input/tablet/gtco.c
> +++ b/drivers/input/tablet/gtco.c
> @@ -850,8 +850,8 @@ static int gtco_probe(struct usb_interface *usbinterface,
> gtco->usbdev = usb_get_dev(interface_to_usbdev(usbinterface));
>
> /* Allocate some data for incoming reports */
> - gtco->buffer = usb_buffer_alloc(gtco->usbdev, REPORT_MAX_SIZE,
> - GFP_KERNEL, &gtco->buf_dma);
> + gtco->buffer = usb_alloc_coherent(gtco->usbdev, REPORT_MAX_SIZE,
> + GFP_KERNEL, &gtco->buf_dma);
> if (!gtco->buffer) {
> err("No more memory for us buffers");
> error = -ENOMEM;
> @@ -982,8 +982,8 @@ static int gtco_probe(struct usb_interface *usbinterface,
> err_free_urb:
> usb_free_urb(gtco->urbinfo);
> err_free_buf:
> - usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE,
> - gtco->buffer, gtco->buf_dma);
> + usb_free_coherent(gtco->usbdev, REPORT_MAX_SIZE,
> + gtco->buffer, gtco->buf_dma);
> err_free_devs:
> input_free_device(input_dev);
> kfree(gtco);
> @@ -1005,8 +1005,8 @@ static void gtco_disconnect(struct usb_interface *interface)
> input_unregister_device(gtco->inputdevice);
> usb_kill_urb(gtco->urbinfo);
> usb_free_urb(gtco->urbinfo);
> - usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE,
> - gtco->buffer, gtco->buf_dma);
> + usb_free_coherent(gtco->usbdev, REPORT_MAX_SIZE,
> + gtco->buffer, gtco->buf_dma);
> kfree(gtco);
> }
>
> diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c
> index 6682b17..d31b9c7 100644
> --- a/drivers/input/tablet/kbtab.c
> +++ b/drivers/input/tablet/kbtab.c
> @@ -129,7 +129,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
> if (!kbtab || !input_dev)
> goto fail1;
>
> - kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma);
> + kbtab->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &kbtab->data_dma);
> if (!kbtab->data)
> goto fail1;
>
> @@ -182,7 +182,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
> return 0;
>
> fail3: usb_free_urb(kbtab->irq);
> - fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
> + fail2: usb_free_coherent(dev, 10, kbtab->data, kbtab->data_dma);
> fail1: input_free_device(input_dev);
> kfree(kbtab);
> return error;
> @@ -197,7 +197,7 @@ static void kbtab_disconnect(struct usb_interface *intf)
> usb_kill_urb(kbtab->irq);
> input_unregister_device(kbtab->dev);
> usb_free_urb(kbtab->irq);
> - usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
> + usb_free_coherent(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
> kfree(kbtab);
> }
> }
> diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
> index 8b5d287..5d5b3c3 100644
> --- a/drivers/input/tablet/wacom_sys.c
> +++ b/drivers/input/tablet/wacom_sys.c
> @@ -556,8 +556,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
> goto fail1;
> }
>
> - wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX,
> - GFP_KERNEL, &wacom->data_dma);
> + wacom_wac->data = usb_alloc_coherent(dev, WACOM_PKGLEN_MAX,
> + GFP_KERNEL, &wacom->data_dma);
> if (!wacom_wac->data) {
> error = -ENOMEM;
> goto fail1;
> @@ -633,7 +633,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
> return 0;
>
> fail3: usb_free_urb(wacom->irq);
> - fail2: usb_buffer_free(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma);
> + fail2: usb_free_coherent(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma);
> fail1: input_free_device(input_dev);
> kfree(wacom);
> kfree(wacom_wac);
> @@ -649,8 +649,8 @@ static void wacom_disconnect(struct usb_interface *intf)
> usb_kill_urb(wacom->irq);
> input_unregister_device(wacom->dev);
> usb_free_urb(wacom->irq);
> - usb_buffer_free(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
> - wacom->wacom_wac->data, wacom->data_dma);
> + usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
> + wacom->wacom_wac->data, wacom->data_dma);
> kfree(wacom->wacom_wac);
> kfree(wacom);
> }
> diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
> index 99330bb..ea41a85 100644
> --- a/drivers/input/touchscreen/usbtouchscreen.c
> +++ b/drivers/input/touchscreen/usbtouchscreen.c
> @@ -1291,8 +1291,8 @@ static void usbtouch_close(struct input_dev *input)
> static void usbtouch_free_buffers(struct usb_device *udev,
> struct usbtouch_usb *usbtouch)
> {
> - usb_buffer_free(udev, usbtouch->type->rept_size,
> - usbtouch->data, usbtouch->data_dma);
> + usb_free_coherent(udev, usbtouch->type->rept_size,
> + usbtouch->data, usbtouch->data_dma);
> kfree(usbtouch->buffer);
> }
>
> @@ -1336,8 +1336,8 @@ static int usbtouch_probe(struct usb_interface *intf,
> if (!type->process_pkt)
> type->process_pkt = usbtouch_process_pkt;
>
> - usbtouch->data = usb_buffer_alloc(udev, type->rept_size,
> - GFP_KERNEL, &usbtouch->data_dma);
> + usbtouch->data = usb_alloc_coherent(udev, type->rept_size,
> + GFP_KERNEL, &usbtouch->data_dma);
> if (!usbtouch->data)
> goto out_free;
>
> diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c
> index f9702e3..86d6893 100644
> --- a/drivers/media/dvb/dvb-usb/usb-urb.c
> +++ b/drivers/media/dvb/dvb-usb/usb-urb.c
> @@ -96,8 +96,9 @@ static int usb_free_stream_buffers(struct usb_data_stream *stream)
> while (stream->buf_num) {
> stream->buf_num--;
> deb_mem("freeing buffer %d\n",stream->buf_num);
> - usb_buffer_free(stream->udev, stream->buf_size,
> - stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]);
> + usb_free_coherent(stream->udev, stream->buf_size,
> + stream->buf_list[stream->buf_num],
> + stream->dma_addr[stream->buf_num]);
> }
> }
>
> @@ -116,7 +117,7 @@ static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num,
> for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
> deb_mem("allocating buffer %d\n",stream->buf_num);
> if (( stream->buf_list[stream->buf_num] =
> - usb_buffer_alloc(stream->udev, size, GFP_ATOMIC,
> + usb_alloc_coherent(stream->udev, size, GFP_ATOMIC,
> &stream->dma_addr[stream->buf_num]) ) == NULL) {
> deb_mem("not enough memory for urb-buffer allocation.\n");
> usb_free_stream_buffers(stream);
> diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
> index 53baccb..fe1b803 100644
> --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
> +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
> @@ -1257,7 +1257,7 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec)
> if(!dec->irq_urb) {
> return -ENOMEM;
> }
> - dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE,
> + dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE,
> GFP_ATOMIC, &dec->irq_dma_handle);
> if(!dec->irq_buffer) {
> usb_free_urb(dec->irq_urb);
> @@ -1550,8 +1550,8 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
>
> usb_free_urb(dec->irq_urb);
>
> - usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
> - dec->irq_buffer, dec->irq_dma_handle);
> + usb_free_coherent(dec->udev,IRQ_PACKET_SIZE,
> + dec->irq_buffer, dec->irq_dma_handle);
>
> if (dec->rc_input_dev) {
> input_unregister_device(dec->rc_input_dev);
> diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
> index 8c140c0..a2a0f79 100644
> --- a/drivers/media/video/au0828/au0828-video.c
> +++ b/drivers/media/video/au0828/au0828-video.c
> @@ -177,7 +177,7 @@ void au0828_uninit_isoc(struct au0828_dev *dev)
> usb_unlink_urb(urb);
>
> if (dev->isoc_ctl.transfer_buffer[i]) {
> - usb_buffer_free(dev->usbdev,
> + usb_free_coherent(dev->usbdev,
> urb->transfer_buffer_length,
> dev->isoc_ctl.transfer_buffer[i],
> urb->transfer_dma);
> @@ -247,7 +247,7 @@ int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
> }
> dev->isoc_ctl.urb[i] = urb;
>
> - dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->usbdev,
> + dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->usbdev,
> sb_size, GFP_KERNEL, &urb->transfer_dma);
> if (!dev->isoc_ctl.transfer_buffer[i]) {
> printk("unable to allocate %i bytes for transfer"
> diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
> index b24eee1..6ccd87d 100644
> --- a/drivers/media/video/cx231xx/cx231xx-core.c
> +++ b/drivers/media/video/cx231xx/cx231xx-core.c
> @@ -679,11 +679,11 @@ void cx231xx_uninit_isoc(struct cx231xx *dev)
> usb_unlink_urb(urb);
>
> if (dev->video_mode.isoc_ctl.transfer_buffer[i]) {
> - usb_buffer_free(dev->udev,
> - urb->transfer_buffer_length,
> - dev->video_mode.isoc_ctl.
> - transfer_buffer[i],
> - urb->transfer_dma);
> + usb_free_coherent(dev->udev,
> + urb->transfer_buffer_length,
> + dev->video_mode.isoc_ctl.
> + transfer_buffer[i],
> + urb->transfer_dma);
> }
> usb_free_urb(urb);
> dev->video_mode.isoc_ctl.urb[i] = NULL;
> @@ -770,8 +770,8 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
> dev->video_mode.isoc_ctl.urb[i] = urb;
>
> dev->video_mode.isoc_ctl.transfer_buffer[i] =
> - usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,
> - &urb->transfer_dma);
> + usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL,
> + &urb->transfer_dma);
> if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) {
> cx231xx_err("unable to allocate %i bytes for transfer"
> " buffer %i%s\n",
> diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
> index a41cc55..d4a9554 100644
> --- a/drivers/media/video/em28xx/em28xx-core.c
> +++ b/drivers/media/video/em28xx/em28xx-core.c
> @@ -966,7 +966,7 @@ void em28xx_uninit_isoc(struct em28xx *dev)
> usb_unlink_urb(urb);
>
> if (dev->isoc_ctl.transfer_buffer[i]) {
> - usb_buffer_free(dev->udev,
> + usb_free_coherent(dev->udev,
> urb->transfer_buffer_length,
> dev->isoc_ctl.transfer_buffer[i],
> urb->transfer_dma);
> @@ -1041,7 +1041,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
> }
> dev->isoc_ctl.urb[i] = urb;
>
> - dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->udev,
> + dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev,
> sb_size, GFP_KERNEL, &urb->transfer_dma);
> if (!dev->isoc_ctl.transfer_buffer[i]) {
> em28xx_err("unable to allocate %i bytes for transfer"
> diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c
> index 43ac4af..fce8d94 100644
> --- a/drivers/media/video/gspca/benq.c
> +++ b/drivers/media/video/gspca/benq.c
> @@ -117,13 +117,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
> return -ENOMEM;
> }
> gspca_dev->urb[n] = urb;
> - urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
> + urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev,
> SD_PKT_SZ * SD_NPKT,
> GFP_KERNEL,
> &urb->transfer_dma);
>
> if (urb->transfer_buffer == NULL) {
> - err("usb_buffer_alloc failed");
> + err("usb_alloc_coherent failed");
> return -ENOMEM;
> }
> urb->dev = gspca_dev->dev;
> diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
> index 222af47..00713f8 100644
> --- a/drivers/media/video/gspca/gspca.c
> +++ b/drivers/media/video/gspca/gspca.c
> @@ -213,7 +213,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
> goto error;
> }
>
> - buffer = usb_buffer_alloc(dev, ep->wMaxPacketSize,
> + buffer = usb_alloc_coherent(dev, ep->wMaxPacketSize,
> GFP_KERNEL, &urb->transfer_dma);
> if (!buffer) {
> ret = -ENOMEM;
> @@ -232,10 +232,10 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
> return ret;
>
> error_submit:
> - usb_buffer_free(dev,
> - urb->transfer_buffer_length,
> - urb->transfer_buffer,
> - urb->transfer_dma);
> + usb_free_coherent(dev,
> + urb->transfer_buffer_length,
> + urb->transfer_buffer,
> + urb->transfer_dma);
> error_buffer:
> usb_free_urb(urb);
> error:
> @@ -272,10 +272,10 @@ static void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)
> if (urb) {
> gspca_dev->int_urb = NULL;
> usb_kill_urb(urb);
> - usb_buffer_free(gspca_dev->dev,
> - urb->transfer_buffer_length,
> - urb->transfer_buffer,
> - urb->transfer_dma);
> + usb_free_coherent(gspca_dev->dev,
> + urb->transfer_buffer_length,
> + urb->transfer_buffer,
> + urb->transfer_dma);
> usb_free_urb(urb);
> }
> }
> @@ -597,10 +597,10 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
> gspca_dev->urb[i] = NULL;
> usb_kill_urb(urb);
> if (urb->transfer_buffer != NULL)
> - usb_buffer_free(gspca_dev->dev,
> - urb->transfer_buffer_length,
> - urb->transfer_buffer,
> - urb->transfer_dma);
> + usb_free_coherent(gspca_dev->dev,
> + urb->transfer_buffer_length,
> + urb->transfer_buffer,
> + urb->transfer_dma);
> usb_free_urb(urb);
> }
> }
> @@ -721,13 +721,13 @@ static int create_urbs(struct gspca_dev *gspca_dev,
> return -ENOMEM;
> }
> gspca_dev->urb[n] = urb;
> - urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
> + urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev,
> bsize,
> GFP_KERNEL,
> &urb->transfer_dma);
>
> if (urb->transfer_buffer == NULL) {
> - err("usb_buffer_alloc failed");
> + err("usb_alloc_coherent failed");
> return -ENOMEM;
> }
> urb->dev = gspca_dev->dev;
> diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
> index 196f82d..b65efe2 100644
> --- a/drivers/media/video/hdpvr/hdpvr-video.c
> +++ b/drivers/media/video/hdpvr/hdpvr-video.c
> @@ -92,8 +92,8 @@ static int hdpvr_free_queue(struct list_head *q)
> buf = list_entry(p, struct hdpvr_buffer, buff_list);
>
> urb = buf->urb;
> - usb_buffer_free(urb->dev, urb->transfer_buffer_length,
> - urb->transfer_buffer, urb->transfer_dma);
> + usb_free_coherent(urb->dev, urb->transfer_buffer_length,
> + urb->transfer_buffer, urb->transfer_dma);
> usb_free_urb(urb);
> tmp = p->next;
> list_del(p);
> @@ -143,8 +143,8 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
> }
> buf->urb = urb;
>
> - mem = usb_buffer_alloc(dev->udev, dev->bulk_in_size, GFP_KERNEL,
> - &urb->transfer_dma);
> + mem = usb_alloc_coherent(dev->udev, dev->bulk_in_size, GFP_KERNEL,
> + &urb->transfer_dma);
> if (!mem) {
> v4l2_err(&dev->v4l2_dev,
> "cannot allocate usb transfer buffer\n");
> diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
> index cf8f18c..7bc2906 100644
> --- a/drivers/media/video/tlg2300/pd-video.c
> +++ b/drivers/media/video/tlg2300/pd-video.c
> @@ -476,10 +476,10 @@ static int prepare_iso_urb(struct video_data *video)
> goto out;
>
> video->urb_array[i] = urb;
> - mem = usb_buffer_alloc(udev,
> - ISO_PKT_SIZE * PK_PER_URB,
> - GFP_KERNEL,
> - &urb->transfer_dma);
> + mem = usb_alloc_coherent(udev,
> + ISO_PKT_SIZE * PK_PER_URB,
> + GFP_KERNEL,
> + &urb->transfer_dma);
>
> urb->complete = urb_complete_iso; /* handler */
> urb->dev = udev;
> @@ -519,8 +519,8 @@ int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
> if (urb == NULL)
> return i;
>
> - mem = usb_buffer_alloc(udev, buf_size, gfp_flags,
> - &urb->transfer_dma);
> + mem = usb_alloc_coherent(udev, buf_size, gfp_flags,
> + &urb->transfer_dma);
> if (mem == NULL)
> return i;
>
> @@ -540,7 +540,7 @@ void free_all_urb_generic(struct urb **urb_array, int num)
> for (i = 0; i < num; i++) {
> urb = urb_array[i];
> if (urb) {
> - usb_buffer_free(urb->dev,
> + usb_free_coherent(urb->dev,
> urb->transfer_buffer_length,
> urb->transfer_buffer,
> urb->transfer_dma);
> diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
> index f7aae22..b9dd74f 100644
> --- a/drivers/media/video/usbvision/usbvision-core.c
> +++ b/drivers/media/video/usbvision/usbvision-core.c
> @@ -2493,10 +2493,10 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
> }
> usbvision->sbuf[bufIdx].urb = urb;
> usbvision->sbuf[bufIdx].data =
> - usb_buffer_alloc(usbvision->dev,
> - sb_size,
> - GFP_KERNEL,
> - &urb->transfer_dma);
> + usb_alloc_coherent(usbvision->dev,
> + sb_size,
> + GFP_KERNEL,
> + &urb->transfer_dma);
> urb->dev = dev;
> urb->context = usbvision;
> urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
> @@ -2552,10 +2552,10 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
> for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
> usb_kill_urb(usbvision->sbuf[bufIdx].urb);
> if (usbvision->sbuf[bufIdx].data){
> - usb_buffer_free(usbvision->dev,
> - sb_size,
> - usbvision->sbuf[bufIdx].data,
> - usbvision->sbuf[bufIdx].urb->transfer_dma);
> + usb_free_coherent(usbvision->dev,
> + sb_size,
> + usbvision->sbuf[bufIdx].data,
> + usbvision->sbuf[bufIdx].urb->transfer_dma);
> }
> usb_free_urb(usbvision->sbuf[bufIdx].urb);
> usbvision->sbuf[bufIdx].urb = NULL;
> diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
> index 821a996..53f3ef4 100644
> --- a/drivers/media/video/uvc/uvc_video.c
> +++ b/drivers/media/video/uvc/uvc_video.c
> @@ -739,7 +739,7 @@ static void uvc_free_urb_buffers(struct uvc_streaming *stream)
>
> for (i = 0; i < UVC_URBS; ++i) {
> if (stream->urb_buffer[i]) {
> - usb_buffer_free(stream->dev->udev, stream->urb_size,
> + usb_free_coherent(stream->dev->udev, stream->urb_size,
> stream->urb_buffer[i], stream->urb_dma[i]);
> stream->urb_buffer[i] = NULL;
> }
> @@ -780,7 +780,7 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
> for (; npackets > 1; npackets /= 2) {
> for (i = 0; i < UVC_URBS; ++i) {
> stream->urb_size = psize * npackets;
> - stream->urb_buffer[i] = usb_buffer_alloc(
> + stream->urb_buffer[i] = usb_alloc_coherent(
> stream->dev->udev, stream->urb_size,
> gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]);
> if (!stream->urb_buffer[i]) {
> diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
> index 3345109..62be62f 100644
> --- a/drivers/net/can/usb/ems_usb.c
> +++ b/drivers/net/can/usb/ems_usb.c
> @@ -516,8 +516,8 @@ static void ems_usb_write_bulk_callback(struct urb *urb)
> netdev = dev->netdev;
>
> /* free up our allocated buffer */
> - usb_buffer_free(urb->dev, urb->transfer_buffer_length,
> - urb->transfer_buffer, urb->transfer_dma);
> + usb_free_coherent(urb->dev, urb->transfer_buffer_length,
> + urb->transfer_buffer, urb->transfer_dma);
>
> atomic_dec(&dev->active_tx_urbs);
>
> @@ -614,8 +614,8 @@ static int ems_usb_start(struct ems_usb *dev)
> return -ENOMEM;
> }
>
> - buf = usb_buffer_alloc(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
> - &urb->transfer_dma);
> + buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
> + &urb->transfer_dma);
> if (!buf) {
> dev_err(netdev->dev.parent,
> "No memory left for USB buffer\n");
> @@ -635,8 +635,8 @@ static int ems_usb_start(struct ems_usb *dev)
> netif_device_detach(dev->netdev);
>
> usb_unanchor_urb(urb);
> - usb_buffer_free(dev->udev, RX_BUFFER_SIZE, buf,
> - urb->transfer_dma);
> + usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
> + urb->transfer_dma);
> break;
> }
>
> @@ -777,7 +777,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
> goto nomem;
> }
>
> - buf = usb_buffer_alloc(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma);
> + buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma);
> if (!buf) {
> dev_err(netdev->dev.parent, "No memory left for USB buffer\n");
> usb_free_urb(urb);
> @@ -820,7 +820,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
> */
> if (!context) {
> usb_unanchor_urb(urb);
> - usb_buffer_free(dev->udev, size, buf, urb->transfer_dma);
> + usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
>
> dev_warn(netdev->dev.parent, "couldn't find free context\n");
>
> @@ -845,7 +845,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
> can_free_echo_skb(netdev, context->echo_index);
>
> usb_unanchor_urb(urb);
> - usb_buffer_free(dev->udev, size, buf, urb->transfer_dma);
> + usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
> dev_kfree_skb(skb);
>
> atomic_dec(&dev->active_tx_urbs);
> diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
> index 52671ea..a790a6d 100644
> --- a/drivers/net/usb/kaweth.c
> +++ b/drivers/net/usb/kaweth.c
> @@ -1155,13 +1155,13 @@ err_fw:
> if (!kaweth->irq_urb)
> goto err_tx_and_rx;
>
> - kaweth->intbuffer = usb_buffer_alloc( kaweth->dev,
> + kaweth->intbuffer = usb_alloc_coherent( kaweth->dev,
> INTBUFFERSIZE,
> GFP_KERNEL,
> &kaweth->intbufferhandle);
> if (!kaweth->intbuffer)
> goto err_tx_and_rx_and_irq;
> - kaweth->rx_buf = usb_buffer_alloc( kaweth->dev,
> + kaweth->rx_buf = usb_alloc_coherent( kaweth->dev,
> KAWETH_BUF_SIZE,
> GFP_KERNEL,
> &kaweth->rxbufferhandle);
> @@ -1202,9 +1202,9 @@ err_fw:
>
> err_intfdata:
> usb_set_intfdata(intf, NULL);
> - usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
> + usb_free_coherent(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
> err_all_but_rxbuf:
> - usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
> + usb_free_coherent(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
> err_tx_and_rx_and_irq:
> usb_free_urb(kaweth->irq_urb);
> err_tx_and_rx:
> @@ -1241,8 +1241,8 @@ static void kaweth_disconnect(struct usb_interface *intf)
> usb_free_urb(kaweth->tx_urb);
> usb_free_urb(kaweth->irq_urb);
>
> - usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
> - usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
> + usb_free_coherent(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
> + usb_free_coherent(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
>
> free_netdev(netdev);
> }
> diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
> index 0b0d2dc..14eda1d 100644
> --- a/drivers/net/wireless/ath/ar9170/usb.c
> +++ b/drivers/net/wireless/ath/ar9170/usb.c
> @@ -200,7 +200,7 @@ resubmit:
> return;
>
> free:
> - usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
> + usb_free_coherent(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
> }
>
> static void ar9170_usb_rx_completed(struct urb *urb)
> @@ -281,7 +281,7 @@ static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
> if (!urb)
> goto out;
>
> - ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
> + ibuf = usb_alloc_coherent(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
> if (!ibuf)
> goto out;
>
> @@ -294,8 +294,8 @@ static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
> err = usb_submit_urb(urb, GFP_KERNEL);
> if (err) {
> usb_unanchor_urb(urb);
> - usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
> - urb->transfer_dma);
> + usb_free_coherent(aru->udev, 64, urb->transfer_buffer,
> + urb->transfer_dma);
> }
>
> out:
> diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
> index d91ad1a..c257940 100644
> --- a/drivers/net/wireless/zd1211rw/zd_usb.c
> +++ b/drivers/net/wireless/zd1211rw/zd_usb.c
> @@ -664,15 +664,15 @@ static struct urb *alloc_rx_urb(struct zd_usb *usb)
> urb = usb_alloc_urb(0, GFP_KERNEL);
> if (!urb)
> return NULL;
> - buffer = usb_buffer_alloc(udev, USB_MAX_RX_SIZE, GFP_KERNEL,
> - &urb->transfer_dma);
> + buffer = usb_alloc_coherent(udev, USB_MAX_RX_SIZE, GFP_KERNEL,
> + &urb->transfer_dma);
> if (!buffer) {
> usb_free_urb(urb);
> return NULL;
> }
>
> usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, EP_DATA_IN),
> - buffer, USB_MAX_RX_SIZE,
> + buffer, USB_MAX_RX_SIZE,
> rx_urb_complete, usb);
> urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
>
> @@ -683,8 +683,8 @@ static void free_rx_urb(struct urb *urb)
> {
> if (!urb)
> return;
> - usb_buffer_free(urb->dev, urb->transfer_buffer_length,
> - urb->transfer_buffer, urb->transfer_dma);
> + usb_free_coherent(urb->dev, urb->transfer_buffer_length,
> + urb->transfer_buffer, urb->transfer_dma);
> usb_free_urb(urb);
> }
>
> diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
> index be6331e..66713ed 100644
> --- a/drivers/usb/class/cdc-acm.c
> +++ b/drivers/usb/class/cdc-acm.c
> @@ -892,7 +892,7 @@ static void acm_write_buffers_free(struct acm *acm)
> struct usb_device *usb_dev = interface_to_usbdev(acm->control);
>
> for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++)
> - usb_buffer_free(usb_dev, acm->writesize, wb->buf, wb->dmah);
> + usb_free_coherent(usb_dev, acm->writesize, wb->buf, wb->dmah);
> }
>
> static void acm_read_buffers_free(struct acm *acm)
> @@ -901,8 +901,8 @@ static void acm_read_buffers_free(struct acm *acm)
> int i, n = acm->rx_buflimit;
>
> for (i = 0; i < n; i++)
> - usb_buffer_free(usb_dev, acm->readsize,
> - acm->rb[i].base, acm->rb[i].dma);
> + usb_free_coherent(usb_dev, acm->readsize,
> + acm->rb[i].base, acm->rb[i].dma);
> }
>
> /* Little helper: write buffers allocate */
> @@ -912,13 +912,13 @@ static int acm_write_buffers_alloc(struct acm *acm)
> struct acm_wb *wb;
>
> for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
> - wb->buf = usb_buffer_alloc(acm->dev, acm->writesize, GFP_KERNEL,
> + wb->buf = usb_alloc_coherent(acm->dev, acm->writesize, GFP_KERNEL,
> &wb->dmah);
> if (!wb->buf) {
> while (i != 0) {
> --i;
> --wb;
> - usb_buffer_free(acm->dev, acm->writesize,
> + usb_free_coherent(acm->dev, acm->writesize,
> wb->buf, wb->dmah);
> }
> return -ENOMEM;
> @@ -1177,7 +1177,7 @@ made_compressed_probe:
> tty_port_init(&acm->port);
> acm->port.ops = &acm_port_ops;
>
> - buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
> + buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
> if (!buf) {
> dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n");
> goto alloc_fail2;
> @@ -1210,11 +1210,11 @@ made_compressed_probe:
> for (i = 0; i < num_rx_buf; i++) {
> struct acm_rb *rb = &(acm->rb[i]);
>
> - rb->base = usb_buffer_alloc(acm->dev, readsize,
> + rb->base = usb_alloc_coherent(acm->dev, readsize,
> GFP_KERNEL, &rb->dma);
> if (!rb->base) {
> dev_dbg(&intf->dev,
> - "out of memory (read bufs usb_buffer_alloc)\n");
> + "out of memory (read bufs usb_alloc_coherent)\n");
> goto alloc_fail7;
> }
> }
> @@ -1306,7 +1306,7 @@ alloc_fail7:
> alloc_fail5:
> acm_write_buffers_free(acm);
> alloc_fail4:
> - usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
> + usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
> alloc_fail2:
> kfree(acm);
> alloc_fail:
> @@ -1356,8 +1356,8 @@ static void acm_disconnect(struct usb_interface *intf)
> stop_data_traffic(acm);
>
> acm_write_buffers_free(acm);
> - usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer,
> - acm->ctrl_dma);
> + usb_free_coherent(usb_dev, acm->ctrlsize, acm->ctrl_buffer,
> + acm->ctrl_dma);
> acm_read_buffers_free(acm);
>
> if (!acm->combined_interfaces)
> diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
> index 189141c..094c76b 100644
> --- a/drivers/usb/class/cdc-wdm.c
> +++ b/drivers/usb/class/cdc-wdm.c
> @@ -276,14 +276,14 @@ static void free_urbs(struct wdm_device *desc)
>
> static void cleanup(struct wdm_device *desc)
> {
> - usb_buffer_free(interface_to_usbdev(desc->intf),
> - desc->wMaxPacketSize,
> - desc->sbuf,
> - desc->validity->transfer_dma);
> - usb_buffer_free(interface_to_usbdev(desc->intf),
> - desc->wMaxCommand,
> - desc->inbuf,
> - desc->response->transfer_dma);
> + usb_free_coherent(interface_to_usbdev(desc->intf),
> + desc->wMaxPacketSize,
> + desc->sbuf,
> + desc->validity->transfer_dma);
> + usb_free_coherent(interface_to_usbdev(desc->intf),
> + desc->wMaxCommand,
> + desc->inbuf,
> + desc->response->transfer_dma);
> kfree(desc->orq);
> kfree(desc->irq);
> kfree(desc->ubuf);
> @@ -705,17 +705,17 @@ next_desc:
> if (!desc->ubuf)
> goto err;
>
> - desc->sbuf = usb_buffer_alloc(interface_to_usbdev(intf),
> + desc->sbuf = usb_alloc_coherent(interface_to_usbdev(intf),
> desc->wMaxPacketSize,
> GFP_KERNEL,
> &desc->validity->transfer_dma);
> if (!desc->sbuf)
> goto err;
>
> - desc->inbuf = usb_buffer_alloc(interface_to_usbdev(intf),
> - desc->bMaxPacketSize0,
> - GFP_KERNEL,
> - &desc->response->transfer_dma);
> + desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf),
> + desc->bMaxPacketSize0,
> + GFP_KERNEL,
> + &desc->response->transfer_dma);
> if (!desc->inbuf)
> goto err2;
>
> @@ -742,15 +742,15 @@ out:
> return rv;
> err3:
> usb_set_intfdata(intf, NULL);
> - usb_buffer_free(interface_to_usbdev(desc->intf),
> - desc->bMaxPacketSize0,
> + usb_free_coherent(interface_to_usbdev(desc->intf),
> + desc->bMaxPacketSize0,
> desc->inbuf,
> desc->response->transfer_dma);
> err2:
> - usb_buffer_free(interface_to_usbdev(desc->intf),
> - desc->wMaxPacketSize,
> - desc->sbuf,
> - desc->validity->transfer_dma);
> + usb_free_coherent(interface_to_usbdev(desc->intf),
> + desc->wMaxPacketSize,
> + desc->sbuf,
> + desc->validity->transfer_dma);
> err:
> free_urbs(desc);
> kfree(desc->ubuf);
> diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
> index 93b5f85..2250095 100644
> --- a/drivers/usb/class/usblp.c
> +++ b/drivers/usb/class/usblp.c
> @@ -27,7 +27,7 @@
> * v0.11 - add proto_bias option (Pete Zaitcev)
> * v0.12 - add hpoj.sourceforge.net ioctls (David Paschal)
> * v0.13 - alloc space for statusbuf (<status> not on stack);
> - * use usb_buffer_alloc() for read buf & write buf;
> + * use usb_alloc_coherent() for read buf & write buf;
> * none - Maintained in Linux kernel after v0.13
> */
>
> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> index 1297e9b..0561430 100644
> --- a/drivers/usb/core/usb.c
> +++ b/drivers/usb/core/usb.c
> @@ -718,7 +718,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
> EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
>
> /**
> - * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
> + * usb_alloc_coherent - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
> * @dev: device the buffer will be used with
> * @size: requested buffer size
> * @mem_flags: affect whether allocation may block
> @@ -737,30 +737,30 @@ EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
> * architectures where CPU caches are not DMA-coherent. On systems without
> * bus-snooping caches, these buffers are uncached.
> *
> - * When the buffer is no longer used, free it with usb_buffer_free().
> + * When the buffer is no longer used, free it with usb_free_coherent().
> */
> -void *usb_buffer_alloc(struct usb_device *dev, size_t size, gfp_t mem_flags,
> - dma_addr_t *dma)
> +void *usb_alloc_coherent(struct usb_device *dev, size_t size, gfp_t mem_flags,
> + dma_addr_t *dma)
> {
> if (!dev || !dev->bus)
> return NULL;
> return hcd_buffer_alloc(dev->bus, size, mem_flags, dma);
> }
> -EXPORT_SYMBOL_GPL(usb_buffer_alloc);
> +EXPORT_SYMBOL_GPL(usb_alloc_coherent);
>
> /**
> - * usb_buffer_free - free memory allocated with usb_buffer_alloc()
> + * usb_free_coherent - free memory allocated with usb_alloc_coherent()
> * @dev: device the buffer was used with
> * @size: requested buffer size
> * @addr: CPU address of buffer
> * @dma: DMA address of buffer
> *
> * This reclaims an I/O buffer, letting it be reused. The memory must have
> - * been allocated using usb_buffer_alloc(), and the parameters must match
> + * been allocated using usb_alloc_coherent(), and the parameters must match
> * those provided in that allocation request.
> */
> -void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
> - dma_addr_t dma)
> +void usb_free_coherent(struct usb_device *dev, size_t size, void *addr,
> + dma_addr_t dma)
> {
> if (!dev || !dev->bus)
> return;
> @@ -768,7 +768,7 @@ void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
> return;
> hcd_buffer_free(dev->bus, size, addr, dma);
> }
> -EXPORT_SYMBOL_GPL(usb_buffer_free);
> +EXPORT_SYMBOL_GPL(usb_free_coherent);
>
> /**
> * usb_buffer_map - create DMA mapping(s) for an urb
> diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
> index 094f91c..1fa6ce3 100644
> --- a/drivers/usb/misc/appledisplay.c
> +++ b/drivers/usb/misc/appledisplay.c
> @@ -259,7 +259,7 @@ static int appledisplay_probe(struct usb_interface *iface,
> }
>
> /* Allocate buffer for interrupt data */
> - pdata->urbdata = usb_buffer_alloc(pdata->udev, ACD_URB_BUFFER_LEN,
> + pdata->urbdata = usb_alloc_coherent(pdata->udev, ACD_URB_BUFFER_LEN,
> GFP_KERNEL, &pdata->urb->transfer_dma);
> if (!pdata->urbdata) {
> retval = -ENOMEM;
> @@ -316,7 +316,7 @@ error:
> if (pdata->urb) {
> usb_kill_urb(pdata->urb);
> if (pdata->urbdata)
> - usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN,
> + usb_free_coherent(pdata->udev, ACD_URB_BUFFER_LEN,
> pdata->urbdata, pdata->urb->transfer_dma);
> usb_free_urb(pdata->urb);
> }
> @@ -337,7 +337,7 @@ static void appledisplay_disconnect(struct usb_interface *iface)
> usb_kill_urb(pdata->urb);
> cancel_delayed_work(&pdata->work);
> backlight_device_unregister(pdata->bd);
> - usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN,
> + usb_free_coherent(pdata->udev, ACD_URB_BUFFER_LEN,
> pdata->urbdata, pdata->urb->transfer_dma);
> usb_free_urb(pdata->urb);
> kfree(pdata->msgdata);
> diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
> index 1edb6d3..a9e0546 100644
> --- a/drivers/usb/misc/ftdi-elan.c
> +++ b/drivers/usb/misc/ftdi-elan.c
> @@ -734,7 +734,7 @@ static void ftdi_elan_write_bulk_callback(struct urb *urb)
> dev_err(&ftdi->udev->dev, "urb=%p write bulk status received: %"
> "d\n", urb, status);
> }
> - usb_buffer_free(urb->dev, urb->transfer_buffer_length,
> + usb_free_coherent(urb->dev, urb->transfer_buffer_length,
> urb->transfer_buffer, urb->transfer_dma);
> }
>
> @@ -795,7 +795,7 @@ static int ftdi_elan_command_engine(struct usb_ftdi *ftdi)
> total_size);
> return -ENOMEM;
> }
> - buf = usb_buffer_alloc(ftdi->udev, total_size, GFP_KERNEL,
> + buf = usb_alloc_coherent(ftdi->udev, total_size, GFP_KERNEL,
> &urb->transfer_dma);
> if (!buf) {
> dev_err(&ftdi->udev->dev, "could not get a buffer to write %d c"
> @@ -829,7 +829,7 @@ static int ftdi_elan_command_engine(struct usb_ftdi *ftdi)
> dev_err(&ftdi->udev->dev, "failed %d to submit urb %p to write "
> "%d commands totaling %d bytes to the Uxxx\n", retval,
> urb, command_size, total_size);
> - usb_buffer_free(ftdi->udev, total_size, buf, urb->transfer_dma);
> + usb_free_coherent(ftdi->udev, total_size, buf, urb->transfer_dma);
> usb_free_urb(urb);
> return retval;
> }
> @@ -1167,7 +1167,7 @@ static ssize_t ftdi_elan_write(struct file *file,
> retval = -ENOMEM;
> goto error_1;
> }
> - buf = usb_buffer_alloc(ftdi->udev, count, GFP_KERNEL,
> + buf = usb_alloc_coherent(ftdi->udev, count, GFP_KERNEL,
> &urb->transfer_dma);
> if (!buf) {
> retval = -ENOMEM;
> @@ -1192,7 +1192,7 @@ static ssize_t ftdi_elan_write(struct file *file,
> exit:
> return count;
> error_3:
> - usb_buffer_free(ftdi->udev, count, buf, urb->transfer_dma);
> + usb_free_coherent(ftdi->udev, count, buf, urb->transfer_dma);
> error_2:
> usb_free_urb(urb);
> error_1:
> @@ -1968,7 +1968,7 @@ static int ftdi_elan_synchronize_flush(struct usb_ftdi *ftdi)
> "ence\n");
> return -ENOMEM;
> }
> - buf = usb_buffer_alloc(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma);
> + buf = usb_alloc_coherent(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma);
> if (!buf) {
> dev_err(&ftdi->udev->dev, "could not get a buffer for flush seq"
> "uence\n");
> @@ -1985,7 +1985,7 @@ static int ftdi_elan_synchronize_flush(struct usb_ftdi *ftdi)
> if (retval) {
> dev_err(&ftdi->udev->dev, "failed to submit urb containing the "
> "flush sequence\n");
> - usb_buffer_free(ftdi->udev, i, buf, urb->transfer_dma);
> + usb_free_coherent(ftdi->udev, i, buf, urb->transfer_dma);
> usb_free_urb(urb);
> return -ENOMEM;
> }
> @@ -2011,7 +2011,7 @@ static int ftdi_elan_synchronize_reset(struct usb_ftdi *ftdi)
> "quence\n");
> return -ENOMEM;
> }
> - buf = usb_buffer_alloc(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma);
> + buf = usb_alloc_coherent(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma);
> if (!buf) {
> dev_err(&ftdi->udev->dev, "could not get a buffer for the reset"
> " sequence\n");
> @@ -2030,7 +2030,7 @@ static int ftdi_elan_synchronize_reset(struct usb_ftdi *ftdi)
> if (retval) {
> dev_err(&ftdi->udev->dev, "failed to submit urb containing the "
> "reset sequence\n");
> - usb_buffer_free(ftdi->udev, i, buf, urb->transfer_dma);
> + usb_free_coherent(ftdi->udev, i, buf, urb->transfer_dma);
> usb_free_urb(urb);
> return -ENOMEM;
> }
> diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
> index d3c8523..7dc9d3c 100644
> --- a/drivers/usb/misc/iowarrior.c
> +++ b/drivers/usb/misc/iowarrior.c
> @@ -239,8 +239,8 @@ static void iowarrior_write_callback(struct urb *urb)
> __func__, status);
> }
> /* free up our allocated buffer */
> - usb_buffer_free(urb->dev, urb->transfer_buffer_length,
> - urb->transfer_buffer, urb->transfer_dma);
> + usb_free_coherent(urb->dev, urb->transfer_buffer_length,
> + urb->transfer_buffer, urb->transfer_dma);
> /* tell a waiting writer the interrupt-out-pipe is available again */
> atomic_dec(&dev->write_busy);
> wake_up_interruptible(&dev->write_wait);
> @@ -421,8 +421,8 @@ static ssize_t iowarrior_write(struct file *file,
> dbg("%s Unable to allocate urb ", __func__);
> goto error_no_urb;
> }
> - buf = usb_buffer_alloc(dev->udev, dev->report_size,
> - GFP_KERNEL, &int_out_urb->transfer_dma);
> + buf = usb_alloc_coherent(dev->udev, dev->report_size,
> + GFP_KERNEL, &int_out_urb->transfer_dma);
> if (!buf) {
> retval = -ENOMEM;
> dbg("%s Unable to allocate buffer ", __func__);
> @@ -459,8 +459,8 @@ static ssize_t iowarrior_write(struct file *file,
> break;
> }
> error:
> - usb_buffer_free(dev->udev, dev->report_size, buf,
> - int_out_urb->transfer_dma);
> + usb_free_coherent(dev->udev, dev->report_size, buf,
> + int_out_urb->transfer_dma);
> error_no_buffer:
> usb_free_urb(int_out_urb);
> error_no_urb:
> diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
> index 90aede9..7828c76 100644
> --- a/drivers/usb/misc/usblcd.c
> +++ b/drivers/usb/misc/usblcd.c
> @@ -205,8 +205,8 @@ static void lcd_write_bulk_callback(struct urb *urb)
> }
>
> /* free up our allocated buffer */
> - usb_buffer_free(urb->dev, urb->transfer_buffer_length,
> - urb->transfer_buffer, urb->transfer_dma);
> + usb_free_coherent(urb->dev, urb->transfer_buffer_length,
> + urb->transfer_buffer, urb->transfer_dma);
> up(&dev->limit_sem);
> }
>
> @@ -234,7 +234,7 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz
> goto err_no_buf;
> }
>
> - buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
> + buf = usb_alloc_coherent(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
> if (!buf) {
> retval = -ENOMEM;
> goto error;
> @@ -268,7 +268,7 @@ exit:
> error_unanchor:
> usb_unanchor_urb(urb);
> error:
> - usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
> + usb_free_coherent(dev->udev, count, buf, urb->transfer_dma);
> usb_free_urb(urb);
> err_no_buf:
> up(&dev->limit_sem);
> diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
> index a21cce6..9ecde8c 100644
> --- a/drivers/usb/misc/usbtest.c
> +++ b/drivers/usb/misc/usbtest.c
> @@ -202,7 +202,7 @@ static struct urb *simple_alloc_urb (
> urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
> if (usb_pipein (pipe))
> urb->transfer_flags |= URB_SHORT_NOT_OK;
> - urb->transfer_buffer = usb_buffer_alloc (udev, bytes, GFP_KERNEL,
> + urb->transfer_buffer = usb_alloc_coherent (udev, bytes, GFP_KERNEL,
> &urb->transfer_dma);
> if (!urb->transfer_buffer) {
> usb_free_urb (urb);
> @@ -272,8 +272,8 @@ static inline int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb)
>
> static void simple_free_urb (struct urb *urb)
> {
> - usb_buffer_free (urb->dev, urb->transfer_buffer_length,
> - urb->transfer_buffer, urb->transfer_dma);
> + usb_free_coherent(urb->dev, urb->transfer_buffer_length,
> + urb->transfer_buffer, urb->transfer_dma);
> usb_free_urb (urb);
> }
>
> @@ -977,7 +977,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
> if (!u)
> goto cleanup;
>
> - reqp = usb_buffer_alloc (udev, sizeof *reqp, GFP_KERNEL,
> + reqp = usb_alloc_coherent (udev, sizeof *reqp, GFP_KERNEL,
> &u->setup_dma);
> if (!reqp)
> goto cleanup;
> @@ -1018,9 +1018,9 @@ cleanup:
> continue;
> urb [i]->dev = udev;
> if (urb [i]->setup_packet)
> - usb_buffer_free (udev, sizeof (struct usb_ctrlrequest),
> - urb [i]->setup_packet,
> - urb [i]->setup_dma);
> + usb_free_coherent (udev, sizeof (struct usb_ctrlrequest),
> + urb [i]->setup_packet,
> + urb [i]->setup_dma);
> simple_free_urb (urb [i]);
> }
> kfree (urb);
> @@ -1421,7 +1421,7 @@ static struct urb *iso_alloc_urb (
>
> urb->number_of_packets = packets;
> urb->transfer_buffer_length = bytes;
> - urb->transfer_buffer = usb_buffer_alloc (udev, bytes, GFP_KERNEL,
> + urb->transfer_buffer = usb_alloc_coherent (udev, bytes, GFP_KERNEL,
> &urb->transfer_dma);
> if (!urb->transfer_buffer) {
> usb_free_urb (urb);
> diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
> index 198bb3e..1943be5 100644
> --- a/drivers/usb/storage/onetouch.c
> +++ b/drivers/usb/storage/onetouch.c
> @@ -201,8 +201,8 @@ static int onetouch_connect_input(struct us_data *ss)
> if (!onetouch || !input_dev)
> goto fail1;
>
> - onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
> - GFP_KERNEL, &onetouch->data_dma);
> + onetouch->data = usb_alloc_coherent(udev, ONETOUCH_PKT_LEN,
> + GFP_KERNEL, &onetouch->data_dma);
> if (!onetouch->data)
> goto fail1;
>
> @@ -264,8 +264,8 @@ static int onetouch_connect_input(struct us_data *ss)
> return 0;
>
> fail3: usb_free_urb(onetouch->irq);
> - fail2: usb_buffer_free(udev, ONETOUCH_PKT_LEN,
> - onetouch->data, onetouch->data_dma);
> + fail2: usb_free_coherent(udev, ONETOUCH_PKT_LEN,
> + onetouch->data, onetouch->data_dma);
> fail1: kfree(onetouch);
> input_free_device(input_dev);
> return error;
> @@ -279,8 +279,8 @@ static void onetouch_release_input(void *onetouch_)
> usb_kill_urb(onetouch->irq);
> input_unregister_device(onetouch->dev);
> usb_free_urb(onetouch->irq);
> - usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN,
> - onetouch->data, onetouch->data_dma);
> + usb_free_coherent(onetouch->udev, ONETOUCH_PKT_LEN,
> + onetouch->data, onetouch->data_dma);
> }
> }
>
> diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
> index bbeeb92..ef00584 100644
> --- a/drivers/usb/storage/usb.c
> +++ b/drivers/usb/storage/usb.c
> @@ -408,14 +408,14 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
> usb_set_intfdata(intf, us);
>
> /* Allocate the device-related DMA-mapped buffers */
> - us->cr = usb_buffer_alloc(us->pusb_dev, sizeof(*us->cr),
> + us->cr = usb_alloc_coherent(us->pusb_dev, sizeof(*us->cr),
> GFP_KERNEL, &us->cr_dma);
> if (!us->cr) {
> US_DEBUGP("usb_ctrlrequest allocation failed\n");
> return -ENOMEM;
> }
>
> - us->iobuf = usb_buffer_alloc(us->pusb_dev, US_IOBUF_SIZE,
> + us->iobuf = usb_alloc_coherent(us->pusb_dev, US_IOBUF_SIZE,
> GFP_KERNEL, &us->iobuf_dma);
> if (!us->iobuf) {
> US_DEBUGP("I/O buffer allocation failed\n");
> @@ -759,11 +759,11 @@ static void dissociate_dev(struct us_data *us)
>
> /* Free the device-related DMA-mapped buffers */
> if (us->cr)
> - usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr,
> - us->cr_dma);
> + usb_free_coherent(us->pusb_dev, sizeof(*us->cr), us->cr,
> + us->cr_dma);
> if (us->iobuf)
> - usb_buffer_free(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,
> - us->iobuf_dma);
> + usb_free_coherent(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,
> + us->iobuf_dma);
>
> /* Remove our private data from the interface */
> usb_set_intfdata(us->pusb_intf, NULL);
> diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
> index 6152278..d110588 100644
> --- a/drivers/usb/usb-skeleton.c
> +++ b/drivers/usb/usb-skeleton.c
> @@ -387,8 +387,8 @@ static void skel_write_bulk_callback(struct urb *urb)
> }
>
> /* free up our allocated buffer */
> - usb_buffer_free(urb->dev, urb->transfer_buffer_length,
> - urb->transfer_buffer, urb->transfer_dma);
> + usb_free_coherent(urb->dev, urb->transfer_buffer_length,
> + urb->transfer_buffer, urb->transfer_dma);
> up(&dev->limit_sem);
> }
>
> @@ -442,8 +442,8 @@ static ssize_t skel_write(struct file *file, const char *user_buffer,
> goto error;
> }
>
> - buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL,
> - &urb->transfer_dma);
> + buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
> + &urb->transfer_dma);
> if (!buf) {
> retval = -ENOMEM;
> goto error;
> @@ -491,7 +491,7 @@ error_unanchor:
> usb_unanchor_urb(urb);
> error:
> if (urb) {
> - usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
> + usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
> usb_free_urb(urb);
> }
> up(&dev->limit_sem);
> diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
> index 8e4eacc..748a74b 100644
> --- a/drivers/watchdog/pcwd_usb.c
> +++ b/drivers/watchdog/pcwd_usb.c
> @@ -600,8 +600,8 @@ static inline void usb_pcwd_delete(struct usb_pcwd_private *usb_pcwd)
> {
> usb_free_urb(usb_pcwd->intr_urb);
> if (usb_pcwd->intr_buffer != NULL)
> - usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size,
> - usb_pcwd->intr_buffer, usb_pcwd->intr_dma);
> + usb_free_coherent(usb_pcwd->udev, usb_pcwd->intr_size,
> + usb_pcwd->intr_buffer, usb_pcwd->intr_dma);
> kfree(usb_pcwd);
> }
>
> @@ -671,7 +671,7 @@ static int usb_pcwd_probe(struct usb_interface *interface,
> le16_to_cpu(endpoint->wMaxPacketSize) : 8);
>
> /* set up the memory buffer's */
> - usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size,
> + usb_pcwd->intr_buffer = usb_alloc_coherent(udev, usb_pcwd->intr_size,
> GFP_ATOMIC, &usb_pcwd->intr_dma);
> if (!usb_pcwd->intr_buffer) {
> printk(KERN_ERR PFX "Out of memory\n");
> diff --git a/include/linux/usb.h b/include/linux/usb.h
> index ce1323c..4f485d0 100644
> --- a/include/linux/usb.h
> +++ b/include/linux/usb.h
> @@ -1085,7 +1085,7 @@ typedef void (*usb_complete_t)(struct urb *);
> * Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
> * which tell the host controller driver that no such mapping is needed since
> * the device driver is DMA-aware. For example, a device driver might
> - * allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
> + * allocate a DMA buffer with usb_alloc_coherent() or call usb_buffer_map().
> * When these transfer flags are provided, host controller drivers will
> * attempt to use the dma addresses found in the transfer_dma and/or
> * setup_dma fields rather than determining a dma address themselves.
> @@ -1366,9 +1366,9 @@ static inline int usb_urb_dir_out(struct urb *urb)
> return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT;
> }
>
> -void *usb_buffer_alloc(struct usb_device *dev, size_t size,
> +void *usb_alloc_coherent(struct usb_device *dev, size_t size,
> gfp_t mem_flags, dma_addr_t *dma);
> -void usb_buffer_free(struct usb_device *dev, size_t size,
> +void usb_free_coherent(struct usb_device *dev, size_t size,
> void *addr, dma_addr_t dma);
>
> #if 0
> diff --git a/sound/usb/midi.c b/sound/usb/midi.c
> index c6ee4a1..00f7d8e 100644
> --- a/sound/usb/midi.c
> +++ b/sound/usb/midi.c
> @@ -1046,8 +1046,8 @@ static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
> static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb,
> unsigned int buffer_length)
> {
> - usb_buffer_free(umidi->dev, buffer_length,
> - urb->transfer_buffer, urb->transfer_dma);
> + usb_free_coherent(umidi->dev, buffer_length,
> + urb->transfer_buffer, urb->transfer_dma);
> usb_free_urb(urb);
> }
>
> @@ -1098,8 +1098,8 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
> pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep);
> length = usb_maxpacket(umidi->dev, pipe, 0);
> for (i = 0; i < INPUT_URBS; ++i) {
> - buffer = usb_buffer_alloc(umidi->dev, length, GFP_KERNEL,
> - &ep->urbs[i]->transfer_dma);
> + buffer = usb_alloc_coherent(umidi->dev, length, GFP_KERNEL,
> + &ep->urbs[i]->transfer_dma);
> if (!buffer) {
> snd_usbmidi_in_endpoint_delete(ep);
> return -ENOMEM;
> @@ -1182,9 +1182,9 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
> break;
> }
> for (i = 0; i < OUTPUT_URBS; ++i) {
> - buffer = usb_buffer_alloc(umidi->dev,
> - ep->max_transfer, GFP_KERNEL,
> - &ep->urbs[i].urb->transfer_dma);
> + buffer = usb_alloc_coherent(umidi->dev,
> + ep->max_transfer, GFP_KERNEL,
> + &ep->urbs[i].urb->transfer_dma);
> if (!buffer) {
> snd_usbmidi_out_endpoint_delete(ep);
> return -ENOMEM;
> diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
> index 796d8b2..fb5d68f 100644
> --- a/sound/usb/misc/ua101.c
> +++ b/sound/usb/misc/ua101.c
> @@ -42,7 +42,7 @@ MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}");
> /*
> * This magic value optimizes memory usage efficiency for the UA-101's packet
> * sizes at all sample rates, taking into account the stupid cache pool sizes
> - * that usb_buffer_alloc() uses.
> + * that usb_alloc_coherent() uses.
> */
> #define DEFAULT_QUEUE_LENGTH 21
>
> @@ -1057,7 +1057,7 @@ static int alloc_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
> (unsigned int)MAX_QUEUE_LENGTH);
>
> /*
> - * The cache pool sizes used by usb_buffer_alloc() (128, 512, 2048) are
> + * The cache pool sizes used by usb_alloc_coherent() (128, 512, 2048) are
> * quite bad when used with the packet sizes of this device (e.g. 280,
> * 520, 624). Therefore, we allocate and subdivide entire pages, using
> * a smaller buffer only for the last chunk.
> @@ -1068,8 +1068,8 @@ static int alloc_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
> packets = min(remaining_packets, packets_per_page);
> size = packets * stream->max_packet_bytes;
> stream->buffers[i].addr =
> - usb_buffer_alloc(ua->dev, size, GFP_KERNEL,
> - &stream->buffers[i].dma);
> + usb_alloc_coherent(ua->dev, size, GFP_KERNEL,
> + &stream->buffers[i].dma);
> if (!stream->buffers[i].addr)
> return -ENOMEM;
> stream->buffers[i].size = size;
> @@ -1089,10 +1089,10 @@ static void free_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
> unsigned int i;
>
> for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i)
> - usb_buffer_free(ua->dev,
> - stream->buffers[i].size,
> - stream->buffers[i].addr,
> - stream->buffers[i].dma);
> + usb_free_coherent(ua->dev,
> + stream->buffers[i].size,
> + stream->buffers[i].addr,
> + stream->buffers[i].dma);
> }
>
> static int alloc_stream_urbs(struct ua101 *ua, struct ua101_stream *stream,
> diff --git a/sound/usb/urb.c b/sound/usb/urb.c
> index 5570a2b..8c7b3e5 100644
> --- a/sound/usb/urb.c
> +++ b/sound/usb/urb.c
> @@ -101,9 +101,9 @@ static void release_urb_ctx(struct snd_urb_ctx *u)
> {
> if (u->urb) {
> if (u->buffer_size)
> - usb_buffer_free(u->subs->dev, u->buffer_size,
> - u->urb->transfer_buffer,
> - u->urb->transfer_dma);
> + usb_free_coherent(u->subs->dev, u->buffer_size,
> + u->urb->transfer_buffer,
> + u->urb->transfer_dma);
> usb_free_urb(u->urb);
> u->urb = NULL;
> }
> @@ -154,8 +154,8 @@ void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force)
> release_urb_ctx(&subs->dataurb[i]);
> for (i = 0; i < SYNC_URBS; i++)
> release_urb_ctx(&subs->syncurb[i]);
> - usb_buffer_free(subs->dev, SYNC_URBS * 4,
> - subs->syncbuf, subs->sync_dma);
> + usb_free_coherent(subs->dev, SYNC_URBS * 4,
> + subs->syncbuf, subs->sync_dma);
> subs->syncbuf = NULL;
> subs->nurbs = 0;
> }
> @@ -308,8 +308,8 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
> if (!u->urb)
> goto out_of_memory;
> u->urb->transfer_buffer =
> - usb_buffer_alloc(subs->dev, u->buffer_size, GFP_KERNEL,
> - &u->urb->transfer_dma);
> + usb_alloc_coherent(subs->dev, u->buffer_size, GFP_KERNEL,
> + &u->urb->transfer_dma);
> if (!u->urb->transfer_buffer)
> goto out_of_memory;
> u->urb->pipe = subs->datapipe;
> @@ -321,8 +321,8 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
>
> if (subs->syncpipe) {
> /* allocate and initialize sync urbs */
> - subs->syncbuf = usb_buffer_alloc(subs->dev, SYNC_URBS * 4,
> - GFP_KERNEL, &subs->sync_dma);
> + subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4,
> + GFP_KERNEL, &subs->sync_dma);
> if (!subs->syncbuf)
> goto out_of_memory;
> for (i = 0; i < SYNC_URBS; i++) {
> --
> 1.6.6.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
>

2010-04-13 18:22:51

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Mon, Apr 12, 2010 at 12:57:16PM -0400, Alan Stern wrote:
> On Mon, 12 Apr 2010, Andi Kleen wrote:
> > On Mon, Apr 12, 2010 at 12:17:22PM -0400, Alan Stern wrote:
> > > On Mon, 12 Apr 2010, Andi Kleen wrote:
> > >
> > > > > Well, the sound driver itself doesn't care for any of those things, just
> > > > > like any other USB driver doesn't. The USB core itself of the host
> > > > > controller driver should do, and as far as I can see, it does that, yes.
> > > >
> > > > Hmm, still things must go wrong somewhere. Perhaps need some instrumentation
> > > > to see if all the transfer buffers really hit the PCI mapping functions.
> > >
> > > Such a test has already been carried out earlier in this thread:
> > >
> > > http://marc.info/?l=linux-usb&m=127074587029353&w=2
> > > http://marc.info/?l=linux-usb&m=127076841801051&w=2
> > > http://marc.info/?l=linux-usb&m=127082890510415&w=2
> >
> > Hmm, thanks. But things must still go wrong somewhere, otherwise
> > the GFP_DMA32 wouldn't be needed?
>
> Indeed, something must go wrong somewhere. Since Daniel's patch fixed
> the problem by changing the buffer from a streaming mapping to a
> coherent mapping, it's logical to assume that bad DMA addresses have
> something to do with it. But we don't really know for certain.

Some more ideas to nail this down would be to boot the machine with
mem=4096M and mem=2048M to see whether this makes any difference. Also,
I think it would be interesting to know whether the patch below helps.

As the real reason seems entirely obfuscated, there's unfortunately need
for some trial error approach. Pedro, as you're the only one who can
actually reproduce the problem, do you see any chance to do that?

Thanks,
Daniel


diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 4328cad..26013be 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -560,7 +560,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ?urbs[i]->transfer_buffer =
- ? ? ? ? ? ? ? ? ? ? ? kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
+ ? ? ? ? ? ? ? ? ? ? ? kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL | GFP_DMA);
? ? ? ? ? ? ? ?if (!urbs[i]->transfer_buffer) {
? ? ? ? ? ? ? ? ? ? ? ?log("unable to kmalloc() transfer buffer, OOM!?\n");
? ? ? ? ? ? ? ? ? ? ? ?*ret = -ENOMEM;

2010-04-13 19:27:38

by Alan Stern

[permalink] [raw]
Subject: Re: [PATCH] USB: rename usb_buffer_alloc() and usb_buffer_free()

On Tue, 13 Apr 2010, Daniel Mack wrote:

> On Mon, Apr 12, 2010 at 01:17:25PM +0200, Daniel Mack wrote:
> > For more clearance what the functions actually do,
> >
> > usb_buffer_alloc() is renamed to usb_alloc_coherent()
> > usb_buffer_free() is renamed to usb_free_coherent()
> >
> > They should only be used in code which really needs DMA coherency.
> >
> > All call sites have been changed accordingly, except for staging
> > drivers.
>
> Is this ok? As it's quite big, I think it should be merged soon if there
> are no objections.

I have no objection. All it does is rename a couple of functions.
There's no reason for this to go into 2.6.34; it can wait for the next
merge window.

Alan Stern

2010-04-13 20:26:23

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] USB: rename usb_buffer_alloc() and usb_buffer_free()

On Tue, Apr 13, 2010 at 03:27:36PM -0400, Alan Stern wrote:
> On Tue, 13 Apr 2010, Daniel Mack wrote:
>
> > On Mon, Apr 12, 2010 at 01:17:25PM +0200, Daniel Mack wrote:
> > > For more clearance what the functions actually do,
> > >
> > > usb_buffer_alloc() is renamed to usb_alloc_coherent()
> > > usb_buffer_free() is renamed to usb_free_coherent()
> > >
> > > They should only be used in code which really needs DMA coherency.
> > >
> > > All call sites have been changed accordingly, except for staging
> > > drivers.
> >
> > Is this ok? As it's quite big, I think it should be merged soon if there
> > are no objections.
>
> I have no objection. All it does is rename a couple of functions.
> There's no reason for this to go into 2.6.34; it can wait for the next
> merge window.

I think I will split this up into the following set of patches:
- rename the functions and add a macro for the old names
- rename all in-kernel usages
- rename the staging tree usages
- remove the macros

the first patch can go in to Linus's tree now, to make it easier for the
2nd and 3rd patches to live in linux-next easier as we might need to
look at the usages in other development trees before we can add the last
one.

Sound good?

thanks,

greg k-h

2010-04-13 21:47:08

by Daniel Mack

[permalink] [raw]
Subject: Re: [PATCH] USB: rename usb_buffer_alloc() and usb_buffer_free()

On Tue, Apr 13, 2010 at 01:26:07PM -0700, Greg KH wrote:
> I think I will split this up into the following set of patches:
> - rename the functions and add a macro for the old names
> - rename all in-kernel usages
> - rename the staging tree usages
> - remove the macros
>
> the first patch can go in to Linus's tree now, to make it easier for the
> 2nd and 3rd patches to live in linux-next easier as we might need to
> look at the usages in other development trees before we can add the last
> one.
>
> Sound good?

Yes, thanks a lot.

Daniel

2010-04-13 23:46:45

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 13 April 2010 19:22, Daniel Mack <[email protected]> wrote:
> On Mon, Apr 12, 2010 at 12:57:16PM -0400, Alan Stern wrote:
>> On Mon, 12 Apr 2010, Andi Kleen wrote:
>> > On Mon, Apr 12, 2010 at 12:17:22PM -0400, Alan Stern wrote:
>> > > On Mon, 12 Apr 2010, Andi Kleen wrote:
>> > >
>> > > > > Well, the sound driver itself doesn't care for any of those things, just
>> > > > > like any other USB driver doesn't. The USB core itself of the host
>> > > > > controller driver should do, and as far as I can see, it does that, yes.
>> > > >
>> > > > Hmm, still things must go wrong somewhere. Perhaps need some instrumentation
>> > > > to see if all the transfer buffers really hit the PCI mapping functions.
>> > >
>> > > Such a test has already been carried out earlier in this thread:
>> > >
>> > > ? http://marc.info/?l=linux-usb&m=127074587029353&w=2
>> > > ? http://marc.info/?l=linux-usb&m=127076841801051&w=2
>> > > ? http://marc.info/?l=linux-usb&m=127082890510415&w=2
>> >
>> > Hmm, thanks. But things must still go wrong somewhere, otherwise
>> > the GFP_DMA32 wouldn't be needed?
>>
>> Indeed, something must go wrong somewhere. ?Since Daniel's patch fixed
>> the problem by changing the buffer from a streaming mapping to a
>> coherent mapping, it's logical to assume that bad DMA addresses have
>> something to do with it. ?But we don't really know for certain.
>
> Some more ideas to nail this down would be to boot the machine with
> mem=4096M and mem=2048M to see whether this makes any difference. Also,
> I think it would be interesting to know whether the patch below helps.
>
> As the real reason seems entirely obfuscated, there's unfortunately need
> for some trial error approach. Pedro, as you're the only one who can
> actually reproduce the problem, do you see any chance to do that?
>
> Thanks,
> Daniel
>
>
> diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
> index 4328cad..26013be 100644
> --- a/sound/usb/caiaq/audio.c
> +++ b/sound/usb/caiaq/audio.c
> @@ -560,7 +560,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
> ? ? ? ? ? ? ? ?}
>
> ? ? ? ? ? ? ? ?urbs[i]->transfer_buffer =
> - ? ? ? ? ? ? ? ? ? ? ? kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
> + ? ? ? ? ? ? ? ? ? ? ? kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL | GFP_DMA);
> ? ? ? ? ? ? ? ?if (!urbs[i]->transfer_buffer) {
> ? ? ? ? ? ? ? ? ? ? ? ?log("unable to kmalloc() transfer buffer, OOM!?\n");
> ? ? ? ? ? ? ? ? ? ? ? ?*ret = -ENOMEM;
>
>

Good news, I can't trigger the interference with either:
- mem=2048m
- mem=4096m
- your patch

Any idea why is mem=4096m different than a regular boot since I have 4GB anyway?

Regards,
Pedro

2010-04-14 10:09:53

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 14, 2010 at 12:46:42AM +0100, Pedro Ribeiro wrote:
> On 13 April 2010 19:22, Daniel Mack <[email protected]> wrote:
> > Some more ideas to nail this down would be to boot the machine with
> > mem=4096M and mem=2048M to see whether this makes any difference. Also,
> > I think it would be interesting to know whether the patch below helps.
> >
> > As the real reason seems entirely obfuscated, there's unfortunately need
> > for some trial error approach. Pedro, as you're the only one who can
> > actually reproduce the problem, do you see any chance to do that?
> >
> > Thanks,
> > Daniel
> >
> >
> > diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
> > index 4328cad..26013be 100644
> > --- a/sound/usb/caiaq/audio.c
> > +++ b/sound/usb/caiaq/audio.c
> > @@ -560,7 +560,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
> > ? ? ? ? ? ? ? ?}
> >
> > ? ? ? ? ? ? ? ?urbs[i]->transfer_buffer =
> > - ? ? ? ? ? ? ? ? ? ? ? kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
> > + ? ? ? ? ? ? ? ? ? ? ? kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL | GFP_DMA);
> > ? ? ? ? ? ? ? ?if (!urbs[i]->transfer_buffer) {
> > ? ? ? ? ? ? ? ? ? ? ? ?log("unable to kmalloc() transfer buffer, OOM!?\n");
> > ? ? ? ? ? ? ? ? ? ? ? ?*ret = -ENOMEM;
> >
> >
>
> Good news, I can't trigger the interference with either:
> - mem=2048m
> - mem=4096m
> - your patch

Thanks! So the only thing I can do for now is submit exactly this patch.
At least, it helps you and it shouldn't break anything. The question
remains whether this type of memory should be used for all
transfer_buffers.

> Any idea why is mem=4096m different than a regular boot since I have 4GB anyway?

On Fri, Apr 09, 2010 at 04:11:52PM -0600, Robert Hancock wrote:
> If you have 4GB of RAM then almost certainly you have memory located
> at addresses over 4GB. If you look at the e820 memory map printed at
> the start of dmesg on bootup and see entries with addresses of
> 100000000 or higher reported as usable, then this is the case.

Could you post the these e820 line from your dmesg when booted with
mem=4096?

Daniel

2010-04-14 10:47:37

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 14 April 2010 11:09, Daniel Mack <[email protected]> wrote:

> Thanks! So the only thing I can do for now is submit exactly this patch.
> At least, it helps you and it shouldn't break anything. The question
> remains whether this type of memory should be used for all
> transfer_buffers.
>

Is there any chance you could push this to -stable? I don't care
because I always use the latest kernel, but the next Debian stable and
Ubuntu LTS are going to use 2.6.32.

>> Any idea why is mem=4096m different than a regular boot since I have 4GB anyway?
>
> On Fri, Apr 09, 2010 at 04:11:52PM -0600, Robert Hancock wrote:
>> If you have 4GB of RAM then almost certainly you have memory located
>> at addresses over 4GB. If you look at the e820 memory map printed at
>> the start of dmesg on bootup and see entries with addresses of
>> 100000000 or higher reported as usable, then this is the case.
>
> Could you post the these e820 line from your dmesg when booted with
> mem=4096?
>
> Daniel
>
>

This is the e820 WITHOUT mem=4096m:

[ 0.000000] BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: 0000000000000000 - 000000000009ec00 (usable)
[ 0.000000] BIOS-e820: 000000000009ec00 - 00000000000a0000 (reserved)
[ 0.000000] BIOS-e820: 00000000000dc000 - 0000000000100000 (reserved)
[ 0.000000] BIOS-e820: 0000000000100000 - 00000000bd4a1000 (usable)
[ 0.000000] BIOS-e820: 00000000bd4a1000 - 00000000bd4a7000 (reserved)
[ 0.000000] BIOS-e820: 00000000bd4a7000 - 00000000bd5b8000 (usable)
[ 0.000000] BIOS-e820: 00000000bd5b8000 - 00000000bd60f000 (reserved)
[ 0.000000] BIOS-e820: 00000000bd60f000 - 00000000bd6c6000 (usable)
[ 0.000000] BIOS-e820: 00000000bd6c6000 - 00000000bd6d1000 (ACPI NVS)
[ 0.000000] BIOS-e820: 00000000bd6d1000 - 00000000bd6d4000 (ACPI data)
[ 0.000000] BIOS-e820: 00000000bd6d4000 - 00000000bd6d8000 (reserved)
[ 0.000000] BIOS-e820: 00000000bd6d8000 - 00000000bd6dc000 (ACPI NVS)
[ 0.000000] BIOS-e820: 00000000bd6dc000 - 00000000bd6df000 (reserved)
[ 0.000000] BIOS-e820: 00000000bd6df000 - 00000000bd706000 (ACPI NVS)
[ 0.000000] BIOS-e820: 00000000bd706000 - 00000000bd708000 (ACPI data)
[ 0.000000] BIOS-e820: 00000000bd708000 - 00000000bd90f000 (reserved)
[ 0.000000] BIOS-e820: 00000000bd90f000 - 00000000bd99f000 (ACPI NVS)
[ 0.000000] BIOS-e820: 00000000bd99f000 - 00000000bd9ff000 (ACPI data)
[ 0.000000] BIOS-e820: 00000000bd9ff000 - 00000000bda00000 (usable)
[ 0.000000] BIOS-e820: 00000000bdc00000 - 00000000c0000000 (reserved)
[ 0.000000] BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
[ 0.000000] BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved)
[ 0.000000] BIOS-e820: 00000000fed00000 - 00000000fed00400 (reserved)
[ 0.000000] BIOS-e820: 00000000fed10000 - 00000000fed14000 (reserved)
[ 0.000000] BIOS-e820: 00000000fed18000 - 00000000fed1a000 (reserved)
[ 0.000000] BIOS-e820: 00000000fed1c000 - 00000000fed90000 (reserved)
[ 0.000000] BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)
[ 0.000000] BIOS-e820: 00000000ff800000 - 0000000100000000 (reserved)
[ 0.000000] BIOS-e820: 0000000100000000 - 000000013c000000 (usable)



This is the e820 output WITH mem=4096m

[ 0.000000] BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: 0000000000000000 - 000000000009ec00 (usable)
[ 0.000000] BIOS-e820: 000000000009ec00 - 00000000000a0000 (reserved)
[ 0.000000] BIOS-e820: 00000000000dc000 - 0000000000100000 (reserved)
[ 0.000000] BIOS-e820: 0000000000100000 - 00000000bd4a1000 (usable)
[ 0.000000] BIOS-e820: 00000000bd4a1000 - 00000000bd4a7000 (reserved)
[ 0.000000] BIOS-e820: 00000000bd4a7000 - 00000000bd5b8000 (usable)
[ 0.000000] BIOS-e820: 00000000bd5b8000 - 00000000bd60f000 (reserved)
[ 0.000000] BIOS-e820: 00000000bd60f000 - 00000000bd6c6000 (usable)
[ 0.000000] BIOS-e820: 00000000bd6c6000 - 00000000bd6d1000 (ACPI NVS)
[ 0.000000] BIOS-e820: 00000000bd6d1000 - 00000000bd6d4000 (ACPI data)
[ 0.000000] BIOS-e820: 00000000bd6d4000 - 00000000bd6d8000 (reserved)
[ 0.000000] BIOS-e820: 00000000bd6d8000 - 00000000bd6dc000 (ACPI NVS)
[ 0.000000] BIOS-e820: 00000000bd6dc000 - 00000000bd6df000 (reserved)
[ 0.000000] BIOS-e820: 00000000bd6df000 - 00000000bd706000 (ACPI NVS)
[ 0.000000] BIOS-e820: 00000000bd706000 - 00000000bd708000 (ACPI data)
[ 0.000000] BIOS-e820: 00000000bd708000 - 00000000bd90f000 (reserved)
[ 0.000000] BIOS-e820: 00000000bd90f000 - 00000000bd99f000 (ACPI NVS)
[ 0.000000] BIOS-e820: 00000000bd99f000 - 00000000bd9ff000 (ACPI data)
[ 0.000000] BIOS-e820: 00000000bd9ff000 - 00000000bda00000 (usable)
[ 0.000000] BIOS-e820: 00000000bdc00000 - 00000000c0000000 (reserved)
[ 0.000000] BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
[ 0.000000] BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved)
[ 0.000000] BIOS-e820: 00000000fed00000 - 00000000fed00400 (reserved)
[ 0.000000] BIOS-e820: 00000000fed10000 - 00000000fed14000 (reserved)
[ 0.000000] BIOS-e820: 00000000fed18000 - 00000000fed1a000 (reserved)
[ 0.000000] BIOS-e820: 00000000fed1c000 - 00000000fed90000 (reserved)
[ 0.000000] BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)
[ 0.000000] BIOS-e820: 00000000ff800000 - 0000000100000000 (reserved)
[ 0.000000] BIOS-e820: 0000000100000000 - 000000013c000000 (usable)
[ 0.000000] NX (Execute Disable) protection: active
[ 0.000000] user-defined physical RAM map:
[ 0.000000] user: 0000000000000000 - 000000000009ec00 (usable)
[ 0.000000] user: 000000000009ec00 - 00000000000a0000 (reserved)
[ 0.000000] user: 00000000000dc000 - 0000000000100000 (reserved)
[ 0.000000] user: 0000000000100000 - 00000000bd4a1000 (usable)
[ 0.000000] user: 00000000bd4a1000 - 00000000bd4a7000 (reserved)
[ 0.000000] user: 00000000bd4a7000 - 00000000bd5b8000 (usable)
[ 0.000000] user: 00000000bd5b8000 - 00000000bd60f000 (reserved)
[ 0.000000] user: 00000000bd60f000 - 00000000bd6c6000 (usable)
[ 0.000000] user: 00000000bd6c6000 - 00000000bd6d1000 (ACPI NVS)
[ 0.000000] user: 00000000bd6d1000 - 00000000bd6d4000 (ACPI data)
[ 0.000000] user: 00000000bd6d4000 - 00000000bd6d8000 (reserved)
[ 0.000000] user: 00000000bd6d8000 - 00000000bd6dc000 (ACPI NVS)
[ 0.000000] user: 00000000bd6dc000 - 00000000bd6df000 (reserved)
[ 0.000000] user: 00000000bd6df000 - 00000000bd706000 (ACPI NVS)
[ 0.000000] user: 00000000bd706000 - 00000000bd708000 (ACPI data)
[ 0.000000] user: 00000000bd708000 - 00000000bd90f000 (reserved)
[ 0.000000] user: 00000000bd90f000 - 00000000bd99f000 (ACPI NVS)
[ 0.000000] user: 00000000bd99f000 - 00000000bd9ff000 (ACPI data)
[ 0.000000] user: 00000000bd9ff000 - 00000000bda00000 (usable)
[ 0.000000] user: 00000000bdc00000 - 00000000c0000000 (reserved)
[ 0.000000] user: 00000000e0000000 - 00000000f0000000 (reserved)
[ 0.000000] user: 00000000fec00000 - 00000000fec10000 (reserved)
[ 0.000000] user: 00000000fed00000 - 00000000fed00400 (reserved)
[ 0.000000] user: 00000000fed10000 - 00000000fed14000 (reserved)
[ 0.000000] user: 00000000fed18000 - 00000000fed1a000 (reserved)
[ 0.000000] user: 00000000fed1c000 - 00000000fed90000 (reserved)
[ 0.000000] user: 00000000fee00000 - 00000000fee01000 (reserved)
[ 0.000000] user: 00000000ff800000 - 0000000100000000 (reserved)

So basically the BIOS is incorrectly reporting
BIOS-e820: 0000000100000000 - 000000013c000000 (usable)

right?

Thanks,
Pedro

2010-04-14 11:02:59

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 14 April 2010 11:47, Pedro Ribeiro <[email protected]> wrote:
> On 14 April 2010 11:09, Daniel Mack <[email protected]> wrote:
>
>> Thanks! So the only thing I can do for now is submit exactly this patch.
>> At least, it helps you and it shouldn't break anything. The question
>> remains whether this type of memory should be used for all
>> transfer_buffers.
>>
>
> Is there any chance you could push this to -stable? I don't care
> because I always use the latest kernel, but the next Debian stable and
> Ubuntu LTS are going to use 2.6.32.
>
>>> Any idea why is mem=4096m different than a regular boot since I have 4GB anyway?
>>
>> On Fri, Apr 09, 2010 at 04:11:52PM -0600, Robert Hancock wrote:
>>> If you have 4GB of RAM then almost certainly you have memory located
>>> at addresses over 4GB. If you look at the e820 memory map printed at
>>> the start of dmesg on bootup and see entries with addresses of
>>> 100000000 or higher reported as usable, then this is the case.
>>
>> Could you post the these e820 line from your dmesg when booted with
>> mem=4096?
>>
>> Daniel
>>
>>
>
> This is the e820 WITHOUT mem=4096m:
>
> [ ? ?0.000000] BIOS-provided physical RAM map:
> [ ? ?0.000000] ?BIOS-e820: 0000000000000000 - 000000000009ec00 (usable)
> [ ? ?0.000000] ?BIOS-e820: 000000000009ec00 - 00000000000a0000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000000dc000 - 0000000000100000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 0000000000100000 - 00000000bd4a1000 (usable)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd4a1000 - 00000000bd4a7000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd4a7000 - 00000000bd5b8000 (usable)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd5b8000 - 00000000bd60f000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd60f000 - 00000000bd6c6000 (usable)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6c6000 - 00000000bd6d1000 (ACPI NVS)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6d1000 - 00000000bd6d4000 (ACPI data)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6d4000 - 00000000bd6d8000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6d8000 - 00000000bd6dc000 (ACPI NVS)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6dc000 - 00000000bd6df000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6df000 - 00000000bd706000 (ACPI NVS)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd706000 - 00000000bd708000 (ACPI data)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd708000 - 00000000bd90f000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd90f000 - 00000000bd99f000 (ACPI NVS)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd99f000 - 00000000bd9ff000 (ACPI data)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd9ff000 - 00000000bda00000 (usable)
> [ ? ?0.000000] ?BIOS-e820: 00000000bdc00000 - 00000000c0000000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fed00000 - 00000000fed00400 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fed10000 - 00000000fed14000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fed18000 - 00000000fed1a000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fed1c000 - 00000000fed90000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000ff800000 - 0000000100000000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 0000000100000000 - 000000013c000000 (usable)
>
>
>
> This is the e820 output WITH mem=4096m
>
> [ ? ?0.000000] BIOS-provided physical RAM map:
> [ ? ?0.000000] ?BIOS-e820: 0000000000000000 - 000000000009ec00 (usable)
> [ ? ?0.000000] ?BIOS-e820: 000000000009ec00 - 00000000000a0000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000000dc000 - 0000000000100000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 0000000000100000 - 00000000bd4a1000 (usable)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd4a1000 - 00000000bd4a7000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd4a7000 - 00000000bd5b8000 (usable)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd5b8000 - 00000000bd60f000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd60f000 - 00000000bd6c6000 (usable)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6c6000 - 00000000bd6d1000 (ACPI NVS)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6d1000 - 00000000bd6d4000 (ACPI data)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6d4000 - 00000000bd6d8000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6d8000 - 00000000bd6dc000 (ACPI NVS)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6dc000 - 00000000bd6df000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd6df000 - 00000000bd706000 (ACPI NVS)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd706000 - 00000000bd708000 (ACPI data)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd708000 - 00000000bd90f000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd90f000 - 00000000bd99f000 (ACPI NVS)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd99f000 - 00000000bd9ff000 (ACPI data)
> [ ? ?0.000000] ?BIOS-e820: 00000000bd9ff000 - 00000000bda00000 (usable)
> [ ? ?0.000000] ?BIOS-e820: 00000000bdc00000 - 00000000c0000000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fed00000 - 00000000fed00400 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fed10000 - 00000000fed14000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fed18000 - 00000000fed1a000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fed1c000 - 00000000fed90000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 00000000ff800000 - 0000000100000000 (reserved)
> [ ? ?0.000000] ?BIOS-e820: 0000000100000000 - 000000013c000000 (usable)
> [ ? ?0.000000] NX (Execute Disable) protection: active
> [ ? ?0.000000] user-defined physical RAM map:
> [ ? ?0.000000] ?user: 0000000000000000 - 000000000009ec00 (usable)
> [ ? ?0.000000] ?user: 000000000009ec00 - 00000000000a0000 (reserved)
> [ ? ?0.000000] ?user: 00000000000dc000 - 0000000000100000 (reserved)
> [ ? ?0.000000] ?user: 0000000000100000 - 00000000bd4a1000 (usable)
> [ ? ?0.000000] ?user: 00000000bd4a1000 - 00000000bd4a7000 (reserved)
> [ ? ?0.000000] ?user: 00000000bd4a7000 - 00000000bd5b8000 (usable)
> [ ? ?0.000000] ?user: 00000000bd5b8000 - 00000000bd60f000 (reserved)
> [ ? ?0.000000] ?user: 00000000bd60f000 - 00000000bd6c6000 (usable)
> [ ? ?0.000000] ?user: 00000000bd6c6000 - 00000000bd6d1000 (ACPI NVS)
> [ ? ?0.000000] ?user: 00000000bd6d1000 - 00000000bd6d4000 (ACPI data)
> [ ? ?0.000000] ?user: 00000000bd6d4000 - 00000000bd6d8000 (reserved)
> [ ? ?0.000000] ?user: 00000000bd6d8000 - 00000000bd6dc000 (ACPI NVS)
> [ ? ?0.000000] ?user: 00000000bd6dc000 - 00000000bd6df000 (reserved)
> [ ? ?0.000000] ?user: 00000000bd6df000 - 00000000bd706000 (ACPI NVS)
> [ ? ?0.000000] ?user: 00000000bd706000 - 00000000bd708000 (ACPI data)
> [ ? ?0.000000] ?user: 00000000bd708000 - 00000000bd90f000 (reserved)
> [ ? ?0.000000] ?user: 00000000bd90f000 - 00000000bd99f000 (ACPI NVS)
> [ ? ?0.000000] ?user: 00000000bd99f000 - 00000000bd9ff000 (ACPI data)
> [ ? ?0.000000] ?user: 00000000bd9ff000 - 00000000bda00000 (usable)
> [ ? ?0.000000] ?user: 00000000bdc00000 - 00000000c0000000 (reserved)
> [ ? ?0.000000] ?user: 00000000e0000000 - 00000000f0000000 (reserved)
> [ ? ?0.000000] ?user: 00000000fec00000 - 00000000fec10000 (reserved)
> [ ? ?0.000000] ?user: 00000000fed00000 - 00000000fed00400 (reserved)
> [ ? ?0.000000] ?user: 00000000fed10000 - 00000000fed14000 (reserved)
> [ ? ?0.000000] ?user: 00000000fed18000 - 00000000fed1a000 (reserved)
> [ ? ?0.000000] ?user: 00000000fed1c000 - 00000000fed90000 (reserved)
> [ ? ?0.000000] ?user: 00000000fee00000 - 00000000fee01000 (reserved)
> [ ? ?0.000000] ?user: 00000000ff800000 - 0000000100000000 (reserved)
>
> So basically the BIOS is incorrectly reporting
> BIOS-e820: 0000000100000000 - 000000013c000000 (usable)
>
> right?
>
> Thanks,
> Pedro
>

(sorry for the spam)

Actually this can't be right, because booting with mem=4096m only
gives me 3047008 kb of usable memory, versus 3949684 kb without
mem=4096m.

Pedro

2010-04-14 13:21:04

by Konrad Rzeszutek Wilk

[permalink] [raw]
Subject: Re: [LKML] Re: USB transfer_buffer allocations on 64bit systems

> So basically the BIOS is incorrectly reporting
> BIOS-e820: 0000000100000000 - 000000013c000000 (usable)

No. Count up the the sizes of the (usuable) entries. You will see
that when you provided mem=4GB, the E820 got truncated to stop at 4GB.
Without that it goes past the 4GB mark (which is correct).

Keep in mind, 4GB doesn't mean your usuable memory stops at 4GB. The
BIOS shuffles the memory around to stick in the BIOS, ACPI, PCI hole so
that part of the usable memory is above 4GB.

2010-04-14 14:08:49

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 14 Apr 2010, Pedro Ribeiro wrote:

> On 14 April 2010 11:09, Daniel Mack <[email protected]> wrote:
>
> > Thanks! So the only thing I can do for now is submit exactly this patch.
> > At least, it helps you and it shouldn't break anything. The question
> > remains whether this type of memory should be used for all
> > transfer_buffers.
> >
>
> Is there any chance you could push this to -stable? I don't care
> because I always use the latest kernel, but the next Debian stable and
> Ubuntu LTS are going to use 2.6.32.

No! Please don't do it: Don't submit the patch and _certainly_ don't
submit it to -stable. It doesn't fix anything; it only works around a
bug, and at the moment we don't even know if the bug is in the kernel
or in Pedro's hardware (and even though it affects two different
systems of his, nobody else has reported a similar problem). Papering
over it will only remove the incentive to fix it properly.

In addition, you'll most likely find that lots of Linux developers will
object vociferously to any proposed patch that uses GFP_DMA. That flag
is supposed to be _only_ for ISA devices, which really need it. By
limiting the memory allocation to the lowest 16 MB of physical memory,
it greatly increases the chances that the allocation will fail.

Alan Stern

2010-04-14 16:36:44

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 14, 2010 at 10:08:47AM -0400, Alan Stern wrote:
> On Wed, 14 Apr 2010, Pedro Ribeiro wrote:
> > On 14 April 2010 11:09, Daniel Mack <[email protected]> wrote:
> > > Thanks! So the only thing I can do for now is submit exactly this patch.
> > > At least, it helps you and it shouldn't break anything. The question
> > > remains whether this type of memory should be used for all
> > > transfer_buffers.
> > >
> >
> > Is there any chance you could push this to -stable? I don't care
> > because I always use the latest kernel, but the next Debian stable and
> > Ubuntu LTS are going to use 2.6.32.
>
> No! Please don't do it: Don't submit the patch and _certainly_ don't
> submit it to -stable. It doesn't fix anything; it only works around a
> bug, and at the moment we don't even know if the bug is in the kernel
> or in Pedro's hardware (and even though it affects two different
> systems of his, nobody else has reported a similar problem). Papering
> over it will only remove the incentive to fix it properly.

No worries - I agree. But unfortunately, I'm out of ideas now, and my
initial thoughts about what might cause the trouble were abviously not
able to explain the issue. Does anyone see further steps of tracking
this issue down?

Thanks,
Daniel

2010-04-14 17:21:10

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 14 April 2010 17:36, Daniel Mack <[email protected]> wrote:
> On Wed, Apr 14, 2010 at 10:08:47AM -0400, Alan Stern wrote:
>> On Wed, 14 Apr 2010, Pedro Ribeiro wrote:
>> > On 14 April 2010 11:09, Daniel Mack <[email protected]> wrote:
>> > > Thanks! So the only thing I can do for now is submit exactly this patch.
>> > > At least, it helps you and it shouldn't break anything. The question
>> > > remains whether this type of memory should be used for all
>> > > transfer_buffers.
>> > >
>> >
>> > Is there any chance you could push this to -stable? I don't care
>> > because I always use the latest kernel, but the next Debian stable and
>> > Ubuntu LTS are going to use 2.6.32.
>>
>> No! ?Please don't do it: Don't submit the patch and _certainly_ don't
>> submit it to -stable. ?It doesn't fix anything; it only works around a
>> bug, and at the moment we don't even know if the bug is in the kernel
>> or in Pedro's hardware (and even though it affects two different
>> systems of his, nobody else has reported a similar problem). ?Papering
>> over it will only remove the incentive to fix it properly.
>
> No worries - I agree. But unfortunately, I'm out of ideas now, and my
> initial thoughts about what might cause the trouble were abviously not
> able to explain the issue. Does anyone see further steps of tracking
> this issue down?
>
> Thanks,
> Daniel
>

Well if this is a dirty / dangerous hack, what about your first patch?
I've been testing it for days and has given me no problems.

The best way to trigger the issue is to connect a dib0700 based DVB
adapter. All you need is to connect it. Since it polls for the remote
control every 50 msec, it causes a constant interference. Beware that
on 2.6.34 this behaviour has been corrected. Other DVB adapters may
trigger the same issue if they also poll constatly for the rc.

Regards,
Pedro

2010-04-14 18:15:57

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

[Removed alsa-devel from the CC: list because this doesn't involve ALSA
any more]

On Wed, 14 Apr 2010, Daniel Mack wrote:

> No worries - I agree. But unfortunately, I'm out of ideas now, and my
> initial thoughts about what might cause the trouble were abviously not
> able to explain the issue. Does anyone see further steps of tracking
> this issue down?

Since using mem=4096M or GFP_DMA stopped the symptoms, it seems very
likely that a buffer is getting allocated above the 4 GB line and not
bounced or IOMMU-mapped correctly.

David, do you have anything to suggest? Any ways to check for IOMMU or
related errors?

The problem, in short, is that USB audio doesn't work properly when
Pedro boots a 64-bit kernel on his 4-GB machine. With a 32-bit kernel
it works okay, and it also works if we use dma_alloc_coherent(). The
host controller is limited to 32-bit DMA, and the DMA addresses
generated by dma_map_single() appear to be normal.

At the moment we don't even know if this is caused by a bug in the
kernel or a bug in Pedro's hardware. But he has observed the same
problem on two different machines, both using the ICH9 chipset.

Alan Stern

2010-04-14 18:23:44

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 14 Apr 2010, Pedro Ribeiro wrote:

> The best way to trigger the issue is to connect a dib0700 based DVB
> adapter. All you need is to connect it. Since it polls for the remote
> control every 50 msec, it causes a constant interference. Beware that
> on 2.6.34 this behaviour has been corrected. Other DVB adapters may
> trigger the same issue if they also poll constatly for the rc.

Your computer has two EHCI controllers, doesn't it? Can you plug the
DVB into a different USB bus from the audio device? If you do, does
the interference still occur?

Alan Stern

2010-04-14 18:27:48

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 14 April 2010 19:23, Alan Stern <[email protected]> wrote:
> On Wed, 14 Apr 2010, Pedro Ribeiro wrote:
>
>> The best way to trigger the issue is to connect a dib0700 based DVB
>> adapter. All you need is to connect it. Since it polls for the remote
>> control every 50 msec, it causes a constant interference. Beware that
>> on 2.6.34 this behaviour has been corrected. Other DVB adapters may
>> trigger the same issue if they also poll constatly for the rc.
>
> Your computer has two EHCI controllers, doesn't it? ?Can you plug the
> DVB into a different USB bus from the audio device? ?If you do, does
> the interference still occur?
>
> Alan Stern
>
>

It does not matter on which ports I plug into, even if in different
buses not sharing IRQ's.

Pedro

2010-04-14 18:36:53

by David Woodhouse

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 2010-04-14 at 14:15 -0400, Alan Stern wrote:
>
> Since using mem=4096M or GFP_DMA stopped the symptoms, it seems very
> likely that a buffer is getting allocated above the 4 GB line and not
> bounced or IOMMU-mapped correctly.
>
> David, do you have anything to suggest? Any ways to check for IOMMU
> or related errors?
>
> The problem, in short, is that USB audio doesn't work properly when
> Pedro boots a 64-bit kernel on his 4-GB machine. With a 32-bit kernel
> it works okay, and it also works if we use dma_alloc_coherent(). The
> host controller is limited to 32-bit DMA, and the DMA addresses
> generated by dma_map_single() appear to be normal.
>
> At the moment we don't even know if this is caused by a bug in the
> kernel or a bug in Pedro's hardware. But he has observed the same
> problem on two different machines, both using the ICH9 chipset.

Pedro's dmesg suggests that his machine has an IOMMU, but his kernel
isn't built to support it. So he'll be using swiotlb.

Would be interesting to enable CONFIG_DMAR and check whether the problem
goes away. If so, we can start looking harder at the swiotlb code.

--
David Woodhouse Open Source Technology Centre
[email protected] Intel Corporation

2010-04-14 18:40:33

by Chris Wright

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

* Alan Stern ([email protected]) wrote:
> Since using mem=4096M or GFP_DMA stopped the symptoms, it seems very
> likely that a buffer is getting allocated above the 4 GB line and not
> bounced or IOMMU-mapped correctly.
>
> David, do you have anything to suggest? Any ways to check for IOMMU or
> related errors?

Well if the IOMMU is enabled, dmesg will show you if you're getting DMA
faults due to IOMMU. Doesn't sound like that's the case.

> The problem, in short, is that USB audio doesn't work properly when
> Pedro boots a 64-bit kernel on his 4-GB machine. With a 32-bit kernel
> it works okay, and it also works if we use dma_alloc_coherent(). The
> host controller is limited to 32-bit DMA, and the DMA addresses
> generated by dma_map_single() appear to be normal.

So dma_map_single is the case that's failing, but you think the mask is
correct? What about the direction?

> At the moment we don't even know if this is caused by a bug in the
> kernel or a bug in Pedro's hardware. But he has observed the same
> problem on two different machines, both using the ICH9 chipset.

Is the IOMMU enabled?

$ dmesg | grep -e DMAR -e IOMMU

If it's on, you can boot w/out (intel_iommu=off) or in passthrough mode
(intel_iommu=on iommu=pt) and see if that makes a difference.

If it's not on (but there) you can enable it (intel_iommu=on) and look
for DMA faults (pointing to driver bug).

thanks,
-chris

2010-04-14 18:53:23

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 14 Apr 2010, Pedro Ribeiro wrote:

> On 14 April 2010 19:23, Alan Stern <[email protected]> wrote:
> > On Wed, 14 Apr 2010, Pedro Ribeiro wrote:
> >
> >> The best way to trigger the issue is to connect a dib0700 based DVB
> >> adapter. All you need is to connect it. Since it polls for the remote
> >> control every 50 msec, it causes a constant interference. Beware that
> >> on 2.6.34 this behaviour has been corrected. Other DVB adapters may
> >> trigger the same issue if they also poll constatly for the rc.
> >
> > Your computer has two EHCI controllers, doesn't it? ?Can you plug the
> > DVB into a different USB bus from the audio device? ?If you do, does
> > the interference still occur?
> >
> > Alan Stern
> >
> >
>
> It does not matter on which ports I plug into, even if in different
> buses not sharing IRQ's.

Okay, good. That's important. If the problem went away when the two
devices were on separate buses then it would have to be a bug in
ehci-hcd. But since it didn't go away, it must be a bug in the
memory/buffering code or in the hardware.

Alan Stern

2010-04-14 20:29:24

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 14 Apr 2010, Chris Wright wrote:

> So dma_map_single is the case that's failing, but you think the mask is
> correct? What about the direction?

The mask and direction are unquestionably correct. The mask is set up
by pci_setup_device() and not changed thereafter. Furthermore, the
audio works okay until another device (a DVB tuner) is plugged in.

Alan Stern

2010-04-14 21:03:39

by Konrad Rzeszutek Wilk

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 14, 2010 at 04:29:22PM -0400, Alan Stern wrote:
> On Wed, 14 Apr 2010, Chris Wright wrote:
>
> > So dma_map_single is the case that's failing, but you think the mask is
> > correct? What about the direction?
>
> The mask and direction are unquestionably correct. The mask is set up
> by pci_setup_device() and not changed thereafter. Furthermore, the
> audio works okay until another device (a DVB tuner) is plugged in.

Could the driver for the DVB tuner change the PCI mask? That is, change
the pci mask way after it has been initialized (don't laugh, this did
happend - as I remember 4 months fix was posted on the DRM mailing list
for this).

2010-04-14 21:12:11

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 14 April 2010 19:36, David Woodhouse <[email protected]> wrote:
> On Wed, 2010-04-14 at 14:15 -0400, Alan Stern wrote:
>>
>> Since using mem=4096M or GFP_DMA stopped the symptoms, it seems very
>> likely that a buffer is getting allocated above the 4 GB line and not
>> bounced or IOMMU-mapped correctly.
>>
>> David, do you have anything to suggest? ?Any ways to check for IOMMU
>> or related errors?
>>
>> The problem, in short, is that USB audio doesn't work properly when
>> Pedro boots a 64-bit kernel on his 4-GB machine. ?With a 32-bit kernel
>> it works okay, and it also works if we use dma_alloc_coherent(). ?The
>> host controller is limited to 32-bit DMA, and the DMA addresses
>> generated by dma_map_single() appear to be normal.
>>
>> At the moment we don't even know if this is caused by a bug in the
>> kernel or a bug in Pedro's hardware. ?But he has observed the same
>> problem on two different machines, both using the ICH9 chipset.
>
> Pedro's dmesg suggests that his machine has an IOMMU, but his kernel
> isn't built to support it. So he'll be using swiotlb.
>
> Would be interesting to enable CONFIG_DMAR and check whether the problem
> goes away. If so, we can start looking harder at the swiotlb code.
>
> --
> David Woodhouse ? ? ? ? ? ? ? ? ? ? ? ? ? ?Open Source Technology Centre
> [email protected] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Intel Corporation
>
>

Turns out CONFIG_DMAR was disabled because of PREEMPT_RT. I disabled
the later and enabled _DMAR. It took a long time to boot, something
wrong with the usb ports. You can see it in the appended dmesg from
time 11s to 100s.

Then after it booted, I could barely move my USB mouse and lots of
errors appeared on dmesg. I tried to connect the DVB card but it
wouldn't even initialize.

Enabling it with iommu=pt seemed to make no difference.

Thanks,
Pedro


Attachments:
dmesg.dmar.tar.bz2 (21.87 kB)

2010-04-14 21:12:52

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 14 April 2010 22:01, Konrad Rzeszutek Wilk <[email protected]> wrote:
> On Wed, Apr 14, 2010 at 04:29:22PM -0400, Alan Stern wrote:
>> On Wed, 14 Apr 2010, Chris Wright wrote:
>>
>> > So dma_map_single is the case that's failing, but you think the mask is
>> > correct? ?What about the direction?
>>
>> The mask and direction are unquestionably correct. ?The mask is set up
>> by pci_setup_device() and not changed thereafter. ?Furthermore, the
>> audio works okay until another device (a DVB tuner) is plugged in.
>
> Could the driver for the DVB tuner change the PCI mask? That is, change
> the pci mask way after it has been initialized (don't laugh, this did
> happend - as I remember 4 months fix was posted on the DRM mailing list
> for this).
>

I can also trigger the bug on mount and unmount of a USB stick, albeit
its not as intensive.

Pedro

2010-04-14 22:27:58

by Chris Wright

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

* Pedro Ribeiro ([email protected]) wrote:
> Turns out CONFIG_DMAR was disabled because of PREEMPT_RT. I disabled
> the later and enabled _DMAR. It took a long time to boot, something
> wrong with the usb ports. You can see it in the appended dmesg from
> time 11s to 100s.
>
> Then after it booted, I could barely move my USB mouse and lots of
> errors appeared on dmesg. I tried to connect the DVB card but it
> wouldn't even initialize.

[ 316.360045] DMAR:[DMA Write] Request device [00:02.0] fault addr 23c00000
[ 316.360046] DMAR:[fault reason 05] PTE Write access is not set

That's your video device. Do you have CONFIG_DMAR_BROKEN_GFX_WA=y?

> Enabling it with iommu=pt seemed to make no difference.

It should (it should at least eliminate the video device problem).

2010-04-14 22:57:04

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 14 April 2010 23:25, Chris Wright <[email protected]> wrote:
> * Pedro Ribeiro ([email protected]) wrote:
>> Turns out CONFIG_DMAR was disabled because of PREEMPT_RT. I disabled
>> the later and enabled _DMAR. It took a long time to boot, something
>> wrong with the usb ports. You can see it in the appended dmesg from
>> time 11s to 100s.
>>
>> Then after it booted, I could barely move my USB mouse and lots of
>> errors appeared on dmesg. I tried to connect the DVB card but it
>> wouldn't even initialize.
>
> [ ?316.360045] DMAR:[DMA Write] Request device [00:02.0] fault addr 23c00000
> [ ?316.360046] DMAR:[fault reason 05] PTE Write access is not set
>
> That's your video device. ?Do you have CONFIG_DMAR_BROKEN_GFX_WA=y?
>

Where do I find this option in make menuconfig? Doesn't seem to be available...

>> Enabling it with iommu=pt seemed to make no difference.
>
> It should (it should at least eliminate the video device problem).
>

You are right, it does eliminate that problem. However I can't get any
of the USB devices to work, and the mouse is terribly slow. One more
dmesg attached.

Pedro


Attachments:
dmesg.dmar2.tar.bz2 (20.95 kB)

2010-04-14 23:38:57

by Chris Wright

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

* Pedro Ribeiro ([email protected]) wrote:
> On 14 April 2010 23:25, Chris Wright <[email protected]> wrote:
> > * Pedro Ribeiro ([email protected]) wrote:
> >> Turns out CONFIG_DMAR was disabled because of PREEMPT_RT. I disabled
> >> the later and enabled _DMAR. It took a long time to boot, something
> >> wrong with the usb ports. You can see it in the appended dmesg from
> >> time 11s to 100s.
> >>
> >> Then after it booted, I could barely move my USB mouse and lots of
> >> errors appeared on dmesg. I tried to connect the DVB card but it
> >> wouldn't even initialize.
> >
> > [ ?316.360045] DMAR:[DMA Write] Request device [00:02.0] fault addr 23c00000
> > [ ?316.360046] DMAR:[fault reason 05] PTE Write access is not set
> >
> > That's your video device. ?Do you have CONFIG_DMAR_BROKEN_GFX_WA=y?
>
> Where do I find this option in make menuconfig? Doesn't seem to be available...

It's hidden behind CONFIG_BROKEN. The iommu=pt test puts all devices in
a 1:1 mapping (the broken graphics workaround does that just for all
graphics devices).

> >> Enabling it with iommu=pt seemed to make no difference.
> >
> > It should (it should at least eliminate the video device problem).
>
> You are right, it does eliminate that problem. However I can't get any
> of the USB devices to work, and the mouse is terribly slow. One more
> dmesg attached.

Thanks. It works for me here. I just booted 2.6.33-rt4 on my T400 w/
iommu on, and an external USB mouse is working fine (I don't have the
same number of devices plugged in as you do). You are not seeing DMA
faults which suggest that the IOMMU mappings are correct w.r.t. the DMA
transactions that the controller is initiating.

thanks,
-chris

2010-04-15 01:20:32

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 15 April 2010 00:37, Chris Wright <[email protected]> wrote:
> * Pedro Ribeiro ([email protected]) wrote:
>> On 14 April 2010 23:25, Chris Wright <[email protected]> wrote:
>> > * Pedro Ribeiro ([email protected]) wrote:
>> >> Turns out CONFIG_DMAR was disabled because of PREEMPT_RT. I disabled
>> >> the later and enabled _DMAR. It took a long time to boot, something
>> >> wrong with the usb ports. You can see it in the appended dmesg from
>> >> time 11s to 100s.
>> >>
>> >> Then after it booted, I could barely move my USB mouse and lots of
>> >> errors appeared on dmesg. I tried to connect the DVB card but it
>> >> wouldn't even initialize.
>> >
>> > [ ?316.360045] DMAR:[DMA Write] Request device [00:02.0] fault addr 23c00000
>> > [ ?316.360046] DMAR:[fault reason 05] PTE Write access is not set
>> >
>> > That's your video device. ?Do you have CONFIG_DMAR_BROKEN_GFX_WA=y?
>>
>> Where do I find this option in make menuconfig? Doesn't seem to be available...
>
> It's hidden behind CONFIG_BROKEN. ?The iommu=pt test puts all devices in
> a 1:1 mapping (the broken graphics workaround does that just for all
> graphics devices).
>
>> >> Enabling it with iommu=pt seemed to make no difference.
>> >
>> > It should (it should at least eliminate the video device problem).
>>
>> You are right, it does eliminate that problem. However I can't get any
>> of the USB devices to work, and the mouse is terribly slow. One more
>> dmesg attached.
>
> Thanks. ?It works for me here. ?I just booted 2.6.33-rt4 on my T400 w/
> iommu on, and an external USB mouse is working fine (I don't have the
> same number of devices plugged in as you do). ?You are not seeing DMA
> faults which suggest that the IOMMU mappings are correct w.r.t. the DMA
> transactions that the controller is initiating.
>
> thanks,
> -chris
>

I enabled CONFIG_DMAR_BROKEN_GFX_WA=y and the result is the same. A
delay in the boot process and usb devices don't work properly,
including my USB mouse.

Strange, since you have the same platform as me. The extra usb devices
you were seeing are because of my docking station - but it makes no
difference whether I'm docked or not for the purposes of the original
bug or this situation right now. The dmesg I'm attaching is without
the computer being docked.

Pedro


Attachments:
dmesg.dmar3.tar.bz2 (19.71 kB)

2010-04-15 01:50:55

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, 14 Apr 2010, Pedro Ribeiro wrote:

> On 14 April 2010 22:01, Konrad Rzeszutek Wilk <[email protected]> wrote:
> > On Wed, Apr 14, 2010 at 04:29:22PM -0400, Alan Stern wrote:
> >> On Wed, 14 Apr 2010, Chris Wright wrote:
> >>
> >> > So dma_map_single is the case that's failing, but you think the mask is
> >> > correct? ?What about the direction?
> >>
> >> The mask and direction are unquestionably correct. ?The mask is set up
> >> by pci_setup_device() and not changed thereafter. ?Furthermore, the
> >> audio works okay until another device (a DVB tuner) is plugged in.
> >
> > Could the driver for the DVB tuner change the PCI mask? That is, change
> > the pci mask way after it has been initialized (don't laugh, this did
> > happend - as I remember 4 months fix was posted on the DRM mailing list
> > for this).
> >
>
> I can also trigger the bug on mount and unmount of a USB stick, albeit
> its not as intensive.

In addition, it's worth pointing out that the DVB tuner is another USB
device, not a PCI device. Hence it doesn't have a PCI driver, and it
seems most unlikely that its driver would modify the DMA mask of a
different device.

Alan Stern

2010-04-15 07:35:09

by Daniel Mack

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Wed, Apr 14, 2010 at 06:21:05PM +0100, Pedro Ribeiro wrote:
> On 14 April 2010 17:36, Daniel Mack <[email protected]> wrote:
> > No worries - I agree. But unfortunately, I'm out of ideas now, and my
> > initial thoughts about what might cause the trouble were abviously not
> > able to explain the issue. Does anyone see further steps of tracking
> > this issue down?
> >
> > Thanks,
> > Daniel
> >
>
> Well if this is a dirty / dangerous hack, what about your first patch?
> I've been testing it for days and has given me no problems.

[For those who haven't followed all the discussions - this patch used
usb_buffer_alloc() instead of kmalloc() in the audio USB driver]

No, Alan is right. As long as we don't know what's going on, it
shouldn't be fixed that way.

There might be an update to all USB drivers to use a special allocation
function in order to avoid DMA bounce buffers for non-64-bit aware host
controllers, but that's certainly a second step. First, the bug that you
see needs attention, and the longer you can reproduce it, the better :)

Daniel

2010-04-15 15:20:47

by Alan Stern

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On Thu, 15 Apr 2010, Pedro Ribeiro wrote:

> I enabled CONFIG_DMAR_BROKEN_GFX_WA=y and the result is the same. A
> delay in the boot process and usb devices don't work properly,
> including my USB mouse.
>
> Strange, since you have the same platform as me. The extra usb devices
> you were seeing are because of my docking station - but it makes no
> difference whether I'm docked or not for the purposes of the original
> bug or this situation right now. The dmesg I'm attaching is without
> the computer being docked.

It's not possible to determine the reason for the timeout errors
between timestamps 16 and 53 from the small amount of debugging
information in the log. Clearly something is going wrong with the
communication between the computer and the EHCI controller. And
clearly the kernel config changes are responsible.

But I don't know what to do to track it down any farther.

Alan Stern

2010-04-20 00:17:05

by Pedro Ribeiro

[permalink] [raw]
Subject: Re: USB transfer_buffer allocations on 64bit systems

On 15 April 2010 16:20, Alan Stern <[email protected]> wrote:
> On Thu, 15 Apr 2010, Pedro Ribeiro wrote:
>
>> I enabled ?CONFIG_DMAR_BROKEN_GFX_WA=y and the result is the same. A
>> delay in the boot process and usb devices don't work properly,
>> including my USB mouse.
>>
>> Strange, since you have the same platform as me. The extra usb devices
>> you were seeing are because of my docking station - but it makes no
>> difference whether I'm docked or not for the purposes of the original
>> bug or this situation right now. The dmesg I'm attaching is without
>> the computer being docked.
>
> It's not possible to determine the reason for the timeout errors
> between timestamps 16 and 53 from the small amount of debugging
> information in the log. ?Clearly something is going wrong with the
> communication between the computer and the EHCI controller. ?And
> clearly the kernel config changes are responsible.
>
> But I don't know what to do to track it down any farther.
>
> Alan Stern
>
>

I guess this is pretty much a dead end until anyone else can reproduce it!

I'll continue to use Daniel's patches privately.

Daniel, should I use the big initial patch or the GFP_DMA one? Which
one is better for a system which is only rebooted every week or so (I
usually hibernate)?

Regards,
Pedro