PCI: endpoint: Skip odd BAR when skipping 64bit BAR

Always skip odd BAR when skipping 64bit BARs in pci_epf_test_set_bar()
and pci_epf_test_alloc_space() otherwise pci_epf_test_set_bar() will
call pci_epc_set_bar() on an odd loop index when skipping reserved 64bit
BAR.

Moreover, pci_epf_test_alloc_space() will call pci_epf_alloc_space() on
bind for an odd loop index when BAR is 64bit but leaks on subsequent
unbind by not calling pci_epf_free_space().

Signed-off-by: Alan Mikhak <alan.mikhak@sifive.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
Reviewed-by: Paul Walmsley <paul.walmsley@sifive.com>
This commit is contained in:
Alan Mikhak 2019-05-23 14:55:40 -07:00 committed by Lorenzo Pieralisi
parent f16fb16ed1
commit 3041a64361

View file

@ -389,7 +389,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
static int pci_epf_test_set_bar(struct pci_epf *epf)
{
int bar;
int bar, add;
int ret;
struct pci_epf_bar *epf_bar;
struct pci_epc *epc = epf->epc;
@ -400,8 +400,14 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
epc_features = epf_test->epc_features;
for (bar = BAR_0; bar <= BAR_5; bar++) {
for (bar = BAR_0; bar <= BAR_5; bar += add) {
epf_bar = &epf->bar[bar];
/*
* pci_epc_set_bar() sets PCI_BASE_ADDRESS_MEM_TYPE_64
* if the specific implementation required a 64-bit BAR,
* even if we only requested a 32-bit BAR.
*/
add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
if (!!(epc_features->reserved_bar & (1 << bar)))
continue;
@ -413,13 +419,6 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
if (bar == test_reg_bar)
return ret;
}
/*
* pci_epc_set_bar() sets PCI_BASE_ADDRESS_MEM_TYPE_64
* if the specific implementation required a 64-bit BAR,
* even if we only requested a 32-bit BAR.
*/
if (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
bar++;
}
return 0;
@ -431,7 +430,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
struct device *dev = &epf->dev;
struct pci_epf_bar *epf_bar;
void *base;
int bar;
int bar, add;
enum pci_barno test_reg_bar = epf_test->test_reg_bar;
const struct pci_epc_features *epc_features;
size_t test_reg_size;
@ -451,8 +450,10 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
}
epf_test->reg[test_reg_bar] = base;
for (bar = BAR_0; bar <= BAR_5; bar++) {
for (bar = BAR_0; bar <= BAR_5; bar += add) {
epf_bar = &epf->bar[bar];
add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
if (bar == test_reg_bar)
continue;
@ -465,8 +466,6 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
dev_err(dev, "Failed to allocate space for BAR%d\n",
bar);
epf_test->reg[bar] = base;
if (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
bar++;
}
return 0;