Parent repository is bk://kernel.bkbits.net/gregkh/linux/pci-2.6
======== ChangeSet 1.1601 ========
D 1.1601 04/03/02 18:00:05-08:00 akpm@mnm.(none) 37897 37896 0/0/1
P ChangeSet
C Merge bk://kernel.bkbits.net/gregkh/linux/pci-2.6
C into mnm.(none):/usr/src/bk-pci
------------------------------------------------

diff -Nru a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
--- a/drivers/pci/hotplug/cpqphp.h	Tue Mar  2 18:01:28 2004
+++ b/drivers/pci/hotplug/cpqphp.h	Tue Mar  2 18:01:29 2004
@@ -444,6 +444,7 @@
 
 /* Global variables */
 extern int cpqhp_debug;
+extern int cpqhp_legacy_mode;
 extern struct controller *cpqhp_ctrl_list;
 extern struct pci_func *cpqhp_slot_list[256];
 
diff -Nru a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
--- a/drivers/pci/hotplug/cpqphp_core.c	Tue Mar  2 18:01:28 2004
+++ b/drivers/pci/hotplug/cpqphp_core.c	Tue Mar  2 18:01:28 2004
@@ -49,6 +49,7 @@
 
 /* Global variables */
 int cpqhp_debug;
+int cpqhp_legacy_mode;
 struct controller *cpqhp_ctrl_list;	/* = NULL */
 struct pci_func *cpqhp_slot_list[256];
 
@@ -1169,6 +1170,10 @@
 	 */
 	// The next line is required for cpqhp_find_available_resources
 	ctrl->interrupt = pdev->irq;
+	if (ctrl->interrupt < 0x10) {
+		cpqhp_legacy_mode = 1;
+		dbg("System seems to be configured for Full Table Mapped MPS mode\n");
+	}
 
 	ctrl->cfgspc_irq = 0;
 	pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ctrl->cfgspc_irq);
diff -Nru a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
--- a/drivers/pci/hotplug/cpqphp_ctrl.c	Tue Mar  2 18:01:28 2004
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c	Tue Mar  2 18:01:28 2004
@@ -3020,33 +3020,34 @@
 				}
 			}
 		}		// End of base register loop
+		if (cpqhp_legacy_mode) {
+			// Figure out which interrupt pin this function uses
+			rc = pci_bus_read_config_byte (pci_bus, devfn, 
+				PCI_INTERRUPT_PIN, &temp_byte);
 
-#if !defined(CONFIG_X86_IO_APIC)
-		// Figure out which interrupt pin this function uses
-		rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_INTERRUPT_PIN, &temp_byte);
-
-		// If this function needs an interrupt and we are behind a bridge
-		// and the pin is tied to something that's alread mapped,
-		// set this one the same
-		if (temp_byte && resources->irqs && 
-		    (resources->irqs->valid_INT & 
-		     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
-			// We have to share with something already set up
-			IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
-		} else {
-			// Program IRQ based on card type
-			rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
-
-			if (class_code == PCI_BASE_CLASS_STORAGE) {
-				IRQ = cpqhp_disk_irq;
+			// If this function needs an interrupt and we are behind a bridge
+			// and the pin is tied to something that's alread mapped,
+			// set this one the same
+			if (temp_byte && resources->irqs && 
+			    (resources->irqs->valid_INT & 
+			     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
+				// We have to share with something already set up
+				IRQ = resources->irqs->interrupt[(temp_byte + 
+					resources->irqs->barber_pole - 1) & 0x03];
 			} else {
-				IRQ = cpqhp_nic_irq;
+				// Program IRQ based on card type
+				rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+
+				if (class_code == PCI_BASE_CLASS_STORAGE) {
+					IRQ = cpqhp_disk_irq;
+				} else {
+					IRQ = cpqhp_nic_irq;
+				}
 			}
-		}
 
-		// IRQ Line
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
-#endif
+			// IRQ Line
+			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
+		}
 
 		if (!behind_bridge) {
 			rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
diff -Nru a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
--- a/drivers/pci/hotplug/cpqphp_pci.c	Tue Mar  2 18:01:29 2004
+++ b/drivers/pci/hotplug/cpqphp_pci.c	Tue Mar  2 18:01:29 2004
@@ -151,32 +151,32 @@
  */
 int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
 {
-#if !defined(CONFIG_X86_IO_APIC)	
 	int rc;
 	u16 temp_word;
 	struct pci_dev fakedev;
 	struct pci_bus fakebus;
 
-	fakedev.devfn = dev_num << 3;
-	fakedev.bus = &fakebus;
-	fakebus.number = bus_num;
-	dbg("%s: dev %d, bus %d, pin %d, num %d\n",
-	    __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
-	rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
-	dbg("%s: rc %d\n", __FUNCTION__, rc);
-	if (!rc)
-		return !rc;
+	if (cpqhp_legacy_mode) {
+		fakedev.devfn = dev_num << 3;
+		fakedev.bus = &fakebus;
+		fakebus.number = bus_num;
+		dbg("%s: dev %d, bus %d, pin %d, num %d\n",
+		    __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
+		rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
+		dbg("%s: rc %d\n", __FUNCTION__, rc);
+		if (!rc)
+			return !rc;
 
-	// set the Edge Level Control Register (ELCR)
-	temp_word = inb(0x4d0);
-	temp_word |= inb(0x4d1) << 8;
+		// set the Edge Level Control Register (ELCR)
+		temp_word = inb(0x4d0);
+		temp_word |= inb(0x4d1) << 8;
 
-	temp_word |= 0x01 << irq_num;
+		temp_word |= 0x01 << irq_num;
 
-	// This should only be for x86 as it sets the Edge Level Control Register
-	outb((u8) (temp_word & 0xFF), 0x4d0);
-	outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
-#endif
+		// This should only be for x86 as it sets the Edge Level Control Register
+		outb((u8) (temp_word & 0xFF), 0x4d0);
+		outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
+	}
 
 	return 0;
 }
diff -Nru a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
--- a/drivers/pci/hotplug/pci_hotplug_core.c	Tue Mar  2 18:01:28 2004
+++ b/drivers/pci/hotplug/pci_hotplug_core.c	Tue Mar  2 18:01:28 2004
@@ -104,8 +104,19 @@
 	.release = &hotplug_slot_release,
 };
 
-decl_subsys(pci_hotplug_slots, &hotplug_slot_ktype, NULL);
-
+/* 
+ * We create a struct subsystem on our own and not use decl_subsys so
+ * we can have a sane name "slots" in sysfs, yet still keep a good
+ * global variable name "pci_hotplug_slots_subsys.
+ * If the decl_subsys() #define ever changes, this declaration will
+ * need to be update to make sure everything is initialized properly.
+ */
+struct subsystem pci_hotplug_slots_subsys = {
+	.kset = {
+		.kobj = { .name = "slots" },
+		.ktype = &hotplug_slot_ktype,
+	}
+};
 
 /* these strings match up with the values in pci_bus_speed */
 static char *pci_bus_speed_strings[] = {
@@ -281,7 +292,7 @@
 }
 
 static struct hotplug_slot_attribute hotplug_slot_attr_latch = {
-	.attr = {.name = "latch", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.attr = {.name = "latch", .mode = S_IFREG | S_IRUGO},
 	.show = latch_read_file,
 };
 
@@ -300,7 +311,7 @@
 }
 
 static struct hotplug_slot_attribute hotplug_slot_attr_presence = {
-	.attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO},
 	.show = presence_read_file,
 };
 
@@ -350,7 +361,7 @@
 }
 
 static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = {
-	.attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO},
 	.show = max_bus_speed_read_file,
 };
 
@@ -376,7 +387,7 @@
 }
 
 static struct hotplug_slot_attribute hotplug_slot_attr_cur_bus_speed = {
-	.attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO},
 	.show = cur_bus_speed_read_file,
 };
 
