+
+
+/*
+ * 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 */
+}
+