void pciauto_region_align(struct pci_region *res, unsigned long size)

{

       res->bus_lower = ((res->bus_lower - 1) | (size - 1)) + 1;

}

 

The above function is to do address align with size.

 
Belows is my explanation with example:

According to PCI specification, size must be the power of 2, 

assume Size is 0x100, then size-1 = 0xFF;

(res->bus_lower - 1) | (size - 1) = 0x??????FF;

((res->bus_lower - 1) | (size - 1)) + 1=0x??????00;

So, the result is aligned with size of 0x100.

 

Now let analyse "res->bus_lower", we must divide it into two aspects:

1.       res->bus_lower = 0x??????0?

because or operate with 0x??????FF, substracting 1 is not important.

2.       res->bus_lower = 0x??????00

Obviously, the address is aligned with size of 0x100, so doing substract 1 is necessary,

then the result of ((res->bus_lower - 1) | (size - 1)) + 1  is the same with the original value of res->bus_lower.