|
@@ -68,9 +68,12 @@ static struct airq_struct zpci_airq = {
|
|
|
.isc = PCI_ISC,
|
|
|
};
|
|
|
|
|
|
-/* I/O Map */
|
|
|
+#define ZPCI_IOMAP_ENTRIES \
|
|
|
+ min(((unsigned long) CONFIG_PCI_NR_FUNCTIONS * PCI_BAR_COUNT), \
|
|
|
+ ZPCI_IOMAP_MAX_ENTRIES)
|
|
|
+
|
|
|
static DEFINE_SPINLOCK(zpci_iomap_lock);
|
|
|
-static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
|
|
|
+static unsigned long *zpci_iomap_bitmap;
|
|
|
struct zpci_iomap_entry *zpci_iomap_start;
|
|
|
EXPORT_SYMBOL_GPL(zpci_iomap_start);
|
|
|
|
|
@@ -265,27 +268,20 @@ void __iomem *pci_iomap_range(struct pci_dev *pdev,
|
|
|
unsigned long max)
|
|
|
{
|
|
|
struct zpci_dev *zdev = to_zpci(pdev);
|
|
|
- u64 addr;
|
|
|
int idx;
|
|
|
|
|
|
- if ((bar & 7) != bar)
|
|
|
+ if (!pci_resource_len(pdev, bar))
|
|
|
return NULL;
|
|
|
|
|
|
idx = zdev->bars[bar].map_idx;
|
|
|
spin_lock(&zpci_iomap_lock);
|
|
|
- if (zpci_iomap_start[idx].count++) {
|
|
|
- BUG_ON(zpci_iomap_start[idx].fh != zdev->fh ||
|
|
|
- zpci_iomap_start[idx].bar != bar);
|
|
|
- } else {
|
|
|
- zpci_iomap_start[idx].fh = zdev->fh;
|
|
|
- zpci_iomap_start[idx].bar = bar;
|
|
|
- }
|
|
|
/* Detect overrun */
|
|
|
- BUG_ON(!zpci_iomap_start[idx].count);
|
|
|
+ WARN_ON(!++zpci_iomap_start[idx].count);
|
|
|
+ zpci_iomap_start[idx].fh = zdev->fh;
|
|
|
+ zpci_iomap_start[idx].bar = bar;
|
|
|
spin_unlock(&zpci_iomap_lock);
|
|
|
|
|
|
- addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48);
|
|
|
- return (void __iomem *) addr + offset;
|
|
|
+ return (void __iomem *) ZPCI_ADDR(idx) + offset;
|
|
|
}
|
|
|
EXPORT_SYMBOL(pci_iomap_range);
|
|
|
|
|
@@ -297,12 +293,11 @@ EXPORT_SYMBOL(pci_iomap);
|
|
|
|
|
|
void pci_iounmap(struct pci_dev *pdev, void __iomem *addr)
|
|
|
{
|
|
|
- unsigned int idx;
|
|
|
+ unsigned int idx = ZPCI_IDX(addr);
|
|
|
|
|
|
- idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48;
|
|
|
spin_lock(&zpci_iomap_lock);
|
|
|
/* Detect underrun */
|
|
|
- BUG_ON(!zpci_iomap_start[idx].count);
|
|
|
+ WARN_ON(!zpci_iomap_start[idx].count);
|
|
|
if (!--zpci_iomap_start[idx].count) {
|
|
|
zpci_iomap_start[idx].fh = 0;
|
|
|
zpci_iomap_start[idx].bar = 0;
|
|
@@ -544,15 +539,15 @@ static void zpci_irq_exit(void)
|
|
|
|
|
|
static int zpci_alloc_iomap(struct zpci_dev *zdev)
|
|
|
{
|
|
|
- int entry;
|
|
|
+ unsigned long entry;
|
|
|
|
|
|
spin_lock(&zpci_iomap_lock);
|
|
|
- entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
|
|
|
- if (entry == ZPCI_IOMAP_MAX_ENTRIES) {
|
|
|
+ entry = find_first_zero_bit(zpci_iomap_bitmap, ZPCI_IOMAP_ENTRIES);
|
|
|
+ if (entry == ZPCI_IOMAP_ENTRIES) {
|
|
|
spin_unlock(&zpci_iomap_lock);
|
|
|
return -ENOSPC;
|
|
|
}
|
|
|
- set_bit(entry, zpci_iomap);
|
|
|
+ set_bit(entry, zpci_iomap_bitmap);
|
|
|
spin_unlock(&zpci_iomap_lock);
|
|
|
return entry;
|
|
|
}
|
|
@@ -561,7 +556,7 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry)
|
|
|
{
|
|
|
spin_lock(&zpci_iomap_lock);
|
|
|
memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry));
|
|
|
- clear_bit(entry, zpci_iomap);
|
|
|
+ clear_bit(entry, zpci_iomap_bitmap);
|
|
|
spin_unlock(&zpci_iomap_lock);
|
|
|
}
|
|
|
|
|
@@ -611,8 +606,7 @@ static int zpci_setup_bus_resources(struct zpci_dev *zdev,
|
|
|
if (zdev->bars[i].val & 4)
|
|
|
flags |= IORESOURCE_MEM_64;
|
|
|
|
|
|
- addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48);
|
|
|
-
|
|
|
+ addr = ZPCI_ADDR(entry);
|
|
|
size = 1UL << zdev->bars[i].size;
|
|
|
|
|
|
res = __alloc_res(zdev, addr, size, flags);
|
|
@@ -873,23 +867,30 @@ static int zpci_mem_init(void)
|
|
|
zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
|
|
|
16, 0, NULL);
|
|
|
if (!zdev_fmb_cache)
|
|
|
- goto error_zdev;
|
|
|
+ goto error_fmb;
|
|
|
|
|
|
- /* TODO: use realloc */
|
|
|
- zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
|
|
|
- GFP_KERNEL);
|
|
|
+ zpci_iomap_start = kcalloc(ZPCI_IOMAP_ENTRIES,
|
|
|
+ sizeof(*zpci_iomap_start), GFP_KERNEL);
|
|
|
if (!zpci_iomap_start)
|
|
|
goto error_iomap;
|
|
|
- return 0;
|
|
|
|
|
|
+ zpci_iomap_bitmap = kcalloc(BITS_TO_LONGS(ZPCI_IOMAP_ENTRIES),
|
|
|
+ sizeof(*zpci_iomap_bitmap), GFP_KERNEL);
|
|
|
+ if (!zpci_iomap_bitmap)
|
|
|
+ goto error_iomap_bitmap;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+error_iomap_bitmap:
|
|
|
+ kfree(zpci_iomap_start);
|
|
|
error_iomap:
|
|
|
kmem_cache_destroy(zdev_fmb_cache);
|
|
|
-error_zdev:
|
|
|
+error_fmb:
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
static void zpci_mem_exit(void)
|
|
|
{
|
|
|
+ kfree(zpci_iomap_bitmap);
|
|
|
kfree(zpci_iomap_start);
|
|
|
kmem_cache_destroy(zdev_fmb_cache);
|
|
|
}
|