Skip to contentSkip to conversation

alpha pci fixes (test12-pre7)

PATCH Ivan Kokshaysky 1 participant 1 message Dec 7, 2000

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

This should fix at least some of the boot problems reported recently.

- boot failure on Miata with >1Gb of memory, fixed by Jay Estabrook. Address written to the Translated Base Registers of CIA/Pyxis must be shifted by 2.

- fix oops on DP264 caused by Cypress quirk. We cannot call pci_claim_resource() from the quirk code, otherwise on multi-hose machines hose resources would appear to be a sibling, not parent for the resource we want to claim - pcibios_fixup_bus() is called _after_ quirks fixup, thus pci_claim_resource() will always fail. Fortunately, another quite simple fix is possible - just disable resources for standard IDE ports, and generic IDE code will assume legacy addresses.

- off by one check in pci_dma_supported().

- proper calculation of the address space size for 64-bit PCI cards.

- start resource allocation on the root bus from PCIBIOS_MIN_[IO,MEM], not from 0. Otherwise if there is a bridge on the root bus, but no I/O or memory, the bridge's bases would be set too low. This doesn't matter in the I/O case since devices behind the bridge are allocated properly anyway, but could be harmful for memory case - the bridge will block transfers to the ISA sg window from secondary bus.

- sanity check in pci_dma_supported() for bogus regions.

Ivan.

arch/alpha/kernel/core_cia.c +2 -2
diff -urp 2.4.0t12p7/arch/alpha/kernel/core_cia.c linux/arch/alpha/kernel/core_cia.c
@@ -700,11 +700,11 @@ do_init_arch(int is_pyxis)
 
 	*(vip)CIA_IOC_PCI_W1_BASE = 0x40000000 | 1;
 	*(vip)CIA_IOC_PCI_W1_MASK = (0x40000000 - 1) & 0xfff00000;
-	*(vip)CIA_IOC_PCI_T1_BASE = 0;
+	*(vip)CIA_IOC_PCI_T1_BASE = 0 >> 2;
 
 	*(vip)CIA_IOC_PCI_W2_BASE = 0x80000000 | 1;
 	*(vip)CIA_IOC_PCI_W2_MASK = (0x40000000 - 1) & 0xfff00000;
-	*(vip)CIA_IOC_PCI_T2_BASE = 0x40000000;
+	*(vip)CIA_IOC_PCI_T2_BASE = 0x40000000 >> 2;
 
 	*(vip)CIA_IOC_PCI_W3_BASE = 0;
 }
arch/alpha/kernel/pci.c +2 -4
diff -urp 2.4.0t12p7/arch/alpha/kernel/pci.c linux/arch/alpha/kernel/pci.c
@@ -90,10 +90,8 @@ quirk_cypress_ide_ports(struct pci_dev *
 {
 	if (dev->class >> 8 != PCI_CLASS_STORAGE_IDE)
 		return;
-	dev->resource[1].start |= 2;
-	dev->resource[1].end = dev->resource[1].start;
-	pci_claim_resource(dev, 0);
-	pci_claim_resource(dev, 1);
+	dev->resource[0].flags = 0;
+	dev->resource[1].flags = 0;
 }
 
 static void __init
arch/alpha/kernel/pci_iommu.c +2 -2
diff -urp 2.4.0t12p7/arch/alpha/kernel/pci_iommu.c linux/arch/alpha/kernel/pci_iommu.c
@@ -613,10 +613,10 @@ pci_dma_supported(struct pci_dev *pdev, 
 	/* Check that we have a scatter-gather arena that fits.  */
 	hose = pdev ? pdev->sysdata : pci_isa_hose;
 	arena = hose->sg_isa;
-	if (arena && arena->dma_base + arena->size <= mask)
+	if (arena && arena->dma_base + arena->size - 1 <= mask)
 		return 1;
 	arena = hose->sg_pci;
-	if (arena && arena->dma_base + arena->size <= mask)
+	if (arena && arena->dma_base + arena->size - 1 <= mask)
 		return 1;
 
 	return 0;
drivers/pci/pci.c +3 -2
diff -urp 2.4.0t12p7/drivers/pci/pci.c linux/drivers/pci/pci.c
@@ -575,8 +575,9 @@ static void pci_read_bases(struct pci_de
 			pci_write_config_dword(dev, reg+4, ~0);
 			pci_read_config_dword(dev, reg+4, &sz);
 			pci_write_config_dword(dev, reg+4, l);
-			if (sz)
-				res->end = res->start + (((unsigned long) ~sz) << 32);
+			if (~sz)
+				res->end = res->start + 0xffffffff +
+						(((unsigned long) ~sz) << 32);
 #else
 			if (l) {
 				printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", dev->slot_name);
drivers/pci/setup-bus.c +3 -3
diff -urp 2.4.0t12p7/drivers/pci/setup-bus.c linux/drivers/pci/setup-bus.c
@@ -205,7 +205,7 @@ pbus_assign_resources(struct pci_bus *bu
 	}
 }
 
-void __init 
+void __init
 pci_assign_unassigned_resources(void)
 {
 	struct pbus_set_ranges_data ranges;
@@ -215,8 +215,8 @@ pci_assign_unassigned_resources(void)
 	for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) {
 		struct pci_bus *b = pci_bus_b(ln);
 
-		ranges.io_start = b->resource[0]->start;
-		ranges.mem_start = b->resource[1]->start;
+		ranges.io_start = b->resource[0]->start + PCIBIOS_MIN_IO;
+		ranges.mem_start = b->resource[1]->start + PCIBIOS_MIN_MEM;
 		ranges.io_end = ranges.io_start;
 		ranges.mem_end = ranges.mem_start;
 		ranges.found_vga = 0;
drivers/pci/setup-res.c +10 -1
diff -urp 2.4.0t12p7/drivers/pci/setup-res.c linux/drivers/pci/setup-res.c
@@ -136,6 +136,7 @@ pdev_sort_resources(struct pci_dev *dev,
 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 		struct resource *r;
 		struct resource_list *list, *tmp;
+		unsigned long r_size;
 
 		/* PCI-PCI bridges may have I/O ports or
 		   memory on the primary bus */
@@ -144,15 +145,23 @@ pdev_sort_resources(struct pci_dev *dev,
 			continue;
 
 		r = &dev->resource[i];
+		r_size = r->end - r->start;
+		
 		if (!(r->flags & type_mask) || r->parent)
 			continue;
+		if (!r_size) {
+			printk(KERN_WARN "PCI: Ignore bogus resource %d "
+					 "[%lx:%lx] of %s\n",
+					  i, r->start, r->end, dev->name);
+			continue;
+		}
 		for (list = head; ; list = list->next) {
 			unsigned long size = 0;
 			struct resource_list *ln = list->next;
 
 			if (ln)
 				size = ln->res->end - ln->res->start;
-			if (r->end - r->start > size) {
+			if (r_size > size) {
 				tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
 				tmp->next = ln;
 				tmp->res = r;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/