Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 17840
b: refs/heads/master
c: 6ca45a2
h: refs/heads/master
v: v3
  • Loading branch information
Grant Grundler authored and Kyle McMartin committed Jan 11, 2006
1 parent b3b74e6 commit cf176c0
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 110957f0e521c8d14f97bbe955af2fa17bb720bf
refs/heads/master: 6ca45a24ccb847251f71aec8906746d33e99f33e
113 changes: 90 additions & 23 deletions trunk/drivers/parisc/lba_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,11 +695,71 @@ lba_claim_dev_resources(struct pci_dev *dev)
}
}
}


/*
* truncate_pat_collision: Deal with overlaps or outright collisions
* between PAT PDC reported ranges.
*
* Broken PA8800 firmware will report lmmio range that
* overlaps with CPU HPA. Just truncate the lmmio range.
*
* BEWARE: conflicts with this lmmio range may be an
* elmmio range which is pointing down another rope.
*
* FIXME: only deals with one collision per range...theoretically we
* could have several. Supporting more than one collision will get messy.
*/
static unsigned long
truncate_pat_collision(struct resource *root, struct resource *new)
{
unsigned long start = new->start;
unsigned long end = new->end;
struct resource *tmp = root->child;

if (end <= start || start < root->start || !tmp)
return 0;

/* find first overlap */
while (tmp && tmp->end < start)
tmp = tmp->sibling;

/* no entries overlap */
if (!tmp) return 0;

/* found one that starts behind the new one
** Don't need to do anything.
*/
if (tmp->start >= end) return 0;

if (tmp->start <= start) {
/* "front" of new one overlaps */
new->start = tmp->end + 1;

if (tmp->end >= end) {
/* AACCKK! totally overlaps! drop this range. */
return 1;
}
}

if (tmp->end < end ) {
/* "end" of new one overlaps */
new->end = tmp->start - 1;
}

printk(KERN_WARNING "LBA: Truncating lmmio_space [%lx/%lx] "
"to [%lx,%lx]\n",
start, end,
new->start, new->end );

return 0; /* truncation successful */
}

#else
#define lba_claim_dev_resources(dev)
#define lba_claim_dev_resources(dev) do { } while (0)
#define truncate_pat_collision(r,n) (0)
#endif


/*
** The algorithm is generic code.
** But it needs to access local data structures to get the IRQ base.
Expand Down Expand Up @@ -747,6 +807,9 @@ lba_fixup_bus(struct pci_bus *bus)
lba_dump_res(&ioport_resource, 2);
BUG();
}
/* advertize Host bridge resources to PCI bus */
bus->resource[0] = &(ldev->hba.io_space);
i = 1;

if (ldev->hba.elmmio_space.start) {
err = request_resource(&iomem_resource,
Expand All @@ -760,23 +823,35 @@ lba_fixup_bus(struct pci_bus *bus)

/* lba_dump_res(&iomem_resource, 2); */
/* BUG(); */
}
} else
bus->resource[i++] = &(ldev->hba.elmmio_space);
}

err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
if (err < 0) {
/* FIXME overlaps with elmmio will fail here.
* Need to prune (or disable) the distributed range.
*
* BEWARE: conflicts with this lmmio range may be
* elmmio range which is pointing down another rope.
*/

printk("FAILED: lba_fixup_bus() request for "

/* Overlaps with elmmio can (and should) fail here.
* We will prune (or ignore) the distributed range.
*
* FIXME: SBA code should register all elmmio ranges first.
* that would take care of elmmio ranges routed
* to a different rope (already discovered) from
* getting registered *after* LBA code has already
* registered it's distributed lmmio range.
*/
if (truncate_pat_collision(&iomem_resource,
&(ldev->hba.lmmio_space))) {

printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
ldev->hba.lmmio_space.start,
ldev->hba.lmmio_space.end);
} else {
err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
if (err < 0) {
printk(KERN_ERR "FAILED: lba_fixup_bus() request for "
"lmmio_space [%lx/%lx]\n",
ldev->hba.lmmio_space.start,
ldev->hba.lmmio_space.end);
/* lba_dump_res(&iomem_resource, 2); */
} else
bus->resource[i++] = &(ldev->hba.lmmio_space);
}

#ifdef CONFIG_64BIT
Expand All @@ -791,18 +866,10 @@ lba_fixup_bus(struct pci_bus *bus)
lba_dump_res(&iomem_resource, 2);
BUG();
}
bus->resource[i++] = &(ldev->hba.gmmio_space);
}
#endif

/* advertize Host bridge resources to PCI bus */
bus->resource[0] = &(ldev->hba.io_space);
bus->resource[1] = &(ldev->hba.lmmio_space);
i=2;
if (ldev->hba.elmmio_space.start)
bus->resource[i++] = &(ldev->hba.elmmio_space);
if (ldev->hba.gmmio_space.start)
bus->resource[i++] = &(ldev->hba.gmmio_space);

}

list_for_each(ln, &bus->devices) {
Expand Down

0 comments on commit cf176c0

Please sign in to comment.