On Tue, Nov 13, 2012 at 09:15:03AM +0100, Hannes Reinecke wrote:
On 11/13/2012 09:01 AM, Gerd Hoffmann wrote:
Hi,
Although valid, it's not a good idea to use memalign_high for temporary space. One should use memalign_tmp for that purpose.
The thing here is that megasas_fire_cmd() is a generic function, so it needs to work in both 16 and 32-bit environs. So the frame pointer passed to this function needs to reference the same segment.
32-bit mode is relaxed, everything is a flat 32bit ptr and all those funky segment/offset macros do basically nothing.
For 16-bit mode it is very important to get things right ...
And this is where things get confused. I've converted the driver to use memalign_tmp() for allocating space for the frame. Which works.
The strategy ahci uses is to memalign_tmp() the data structures needed for device probing, so they can easily freed in case the port is unused. When a drive is actually found (and registered) the memory for the data structures is allocated again using memalign_low(), so it is permanently available, accessible in 16-bit mode and the 16-bit only code paths don't have to do any memory allocations when kicking transfers.
I think there are code paths where SET_LOWFLAT & friends are used for memory allocated via memalign_tmp(), but that happens in 32bit mode only where it doesn't really matter.
See ahci_port_realloc().
Ah. Thanks for the explanation.
I've converted it now to use memalign_tmplow(), so everybody should be happy.
The memalign_tmp* variants are implicitly free'd once the init section of the code is completed. So, you can't use that for any allocations used during the 16bit runtime phase.
If the memory is to be used during the 16bit runtime, it must be allocated with memalign_low(). If the memory is used only during the 32bit probe phase, then you want to use memalign_tmp().
I wrote up a description of all the allocators, but never got a chance to publish it. I'll see if I can get it out.
-Kevin