Skip to contentSkip to conversation

PCI and PCI Hotplug update for 2.6.6-rc1

PATCH New Greg KH 1 participant 13 messages Apr 15, 2004

Subsystems (8)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

PATCH 1/1 PCI and PCI Hotplug update for 2.6.6-rc1

Hi,

Here are some PCI and PCI hotplug patches for 2.6.6-rc1. These have all been in the -mm tree for a number of weeks now, and contain:
- some pci hotplug driver fixes and updates
- the final pci express patch that enables access to the extended config area.
- DMA mapping constants renamed and moved.

Please pull from:

	bk://linuxusb.bkbits.net/pci-2.6

thanks,

greg k-h

p.s. I'll send these as patches in response to this email to lkml for those who want to see them. Note that some spam filters seem to be flagging my patches as spam, sorry about that :(

 Documentation/DMA-mapping.txt         |   64 +++++-----
 drivers/net/e1000/e1000.h             |    6 
 drivers/net/e1000/e1000_main.c        |    8 -
 drivers/net/ixgb/ixgb.h               |    6 
 drivers/net/ixgb/ixgb_main.c          |    4 
 drivers/pci/hotplug/acpiphp_glue.c    |   38 ++----
 drivers/pci/hotplug/acpiphp_pci.c     |  110 ++++-------------
 drivers/pci/hotplug/pci_hotplug.h     |    2 
 drivers/pci/hotplug/pciehp_ctrl.c     |    6 
 drivers/pci/hotplug/pciehp_hpc.c      |  180 +++++++++++++++++++++++-----
 drivers/pci/hotplug/pciehp_pci.c      |    2 
 drivers/pci/hotplug/rpadlpar_core.c   |   23 +--
 drivers/pci/hotplug/rpaphp.h          |    2 
 drivers/pci/hotplug/rpaphp_core.c     |   23 +--
 drivers/pci/hotplug/rpaphp_pci.c      |    1 
 drivers/pci/hotplug/rpaphp_slot.c     |   80 ++++++------
 drivers/pci/hotplug/shpchp_ctrl.c     |   10 -
 drivers/pci/hotplug/shpchp_hpc.c      |   26 ++--
 drivers/pci/hotplug/shpchprm_acpi.c   |    3 
 drivers/pci/hotplug/shpchprm_legacy.c |   30 ----
 drivers/pci/pci-sysfs.c               |   29 +++-
 drivers/pci/pci.c                     |   63 ++++++++--
 drivers/pci/pci.h                     |    2 
 drivers/pci/probe.c                   |   40 ++++++
 drivers/pci/proc.c                    |   26 ++--
 drivers/pci/quirks.c                  |   11 +
 include/linux/dma-mapping.h           |    3 
 include/linux/pci.h                   |  213 +++++++++++++++++++++++++++++-----
 include/linux/pci_ids.h               |    2 
 29 files changed, 647 insertions(+), 366 deletions(-)

-----

Deepak Saxena:
o PCI: Allow arch-specific pci_set_dma_mask and friends

Dely Sy:
o PCI Hotplug: Fix interpretation of 0/1 for MRL in SHPC & PCI-E hot-plug
o PCI: Updates for PCI Express hot-plug driver

Greg Kroah-Hartman:

  o Cset exclude: [email protected]|ChangeSet|20040323051558|61282

o PCI: add ability to access pci extended config space for PCI Express devices

Jeff Garzik:
o Create PCI_DMA_{64,32]BIT constants, for use in passing to pci_set_{consistent_}dma_mask().

John Rose:
o PCI Hotplug: RPA PCI Hotplug - redundant free

Linda Xie:
o PCI Hotplug: php_phy_location.patch

Matthew Wilcox:
o PCI Hotplug: Rewrite acpiphp detect_used_resource
o PCI Hotplug: Don't up() twice in acpiphp

Randy Dunlap:
o PCI: move DMA_nnBIT_MASK to linux/dma-mapping.h
o PCI: add DMA_{64,32}BIT constants

author
#1 lore raw

PATCH 1/1 PCI and PCI Hotplug update for 2.6.6-rc1

ChangeSet 1.1643.55.1, 2004/03/23 00:15:58-05:00, [email protected]

Create PCI_DMA_{64,32]BIT constants, for use in passing to pci_set_{consistent_}dma_mask().

Use them in e1000 and ixgb.

 Documentation/DMA-mapping.txt |   16 ++++++++--------
 drivers/net/e1000/e1000.h     |    2 --
 drivers/net/ixgb/ixgb.h       |    2 --
 include/linux/pci.h           |    3 +++
 4 files changed, 11 insertions(+), 12 deletions(-)
Documentation/DMA-mapping.txt +8 -8
diff -Nru a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
@@ -132,7 +132,7 @@
 The standard 32-bit addressing PCI device would do something like
 this:
 
-	if (pci_set_dma_mask(pdev, 0xffffffff)) {
+	if (pci_set_dma_mask(pdev, PCI_DMA_32BIT)) {
 		printk(KERN_WARNING
 		       "mydev: No suitable DMA available.\n");
 		goto ignore_this_device;
@@ -151,9 +151,9 @@
 
 	int using_dac;
 
-	if (!pci_set_dma_mask(pdev, 0xffffffffffffffff)) {
+	if (!pci_set_dma_mask(pdev, PCI_DMA_64BIT)) {
 		using_dac = 1;
-	} else if (!pci_set_dma_mask(pdev, 0xffffffff)) {
+	} else if (!pci_set_dma_mask(pdev, PCI_DMA_32BIT)) {
 		using_dac = 0;
 	} else {
 		printk(KERN_WARNING
@@ -166,14 +166,14 @@
 
 	int using_dac, consistent_using_dac;
 
-	if (!pci_set_dma_mask(pdev, 0xffffffffffffffff)) {
+	if (!pci_set_dma_mask(pdev, PCI_DMA_64BIT)) {
 		using_dac = 1;
 	   	consistent_using_dac = 1;
-		pci_set_consistent_dma_mask(pdev, 0xffffffffffffffff)
-	} else if (!pci_set_dma_mask(pdev, 0xffffffff)) {
+		pci_set_consistent_dma_mask(pdev, PCI_DMA_64BIT);
+	} else if (!pci_set_dma_mask(pdev, PCI_DMA_32BIT)) {
 		using_dac = 0;
 		consistent_using_dac = 0;
-		pci_set_consistent_dma_mask(pdev, 0xffffffff)
+		pci_set_consistent_dma_mask(pdev, PCI_DMA_32BIT);
 	} else {
 		printk(KERN_WARNING
 		       "mydev: No suitable DMA available.\n");
@@ -215,7 +215,7 @@
 
 Here is pseudo-code showing how this might be done:
 
-	#define PLAYBACK_ADDRESS_BITS	0xffffffff
+	#define PLAYBACK_ADDRESS_BITS	PCI_DMA_32BIT
 	#define RECORD_ADDRESS_BITS	0x00ffffff
 
 	struct my_sound_card *card;
drivers/net/e1000/e1000.h +0 -2
diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
@@ -74,8 +74,6 @@
 #define BAR_0		0
 #define BAR_1		1
 #define BAR_5		5
-#define PCI_DMA_64BIT	0xffffffffffffffffULL
-#define PCI_DMA_32BIT	0x00000000ffffffffULL
 
 
 struct e1000_adapter;
drivers/net/ixgb/ixgb.h +0 -2
diff -Nru a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
@@ -65,8 +65,6 @@
 #define BAR_0           0
 #define BAR_1           1
 #define BAR_5           5
-#define PCI_DMA_64BIT   0xffffffffffffffffULL
-#define PCI_DMA_32BIT   0x00000000ffffffffULL
 
 #include "ixgb_hw.h"
 #include "ixgb_ee.h"
include/linux/pci.h +3 -0
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
@@ -362,6 +362,9 @@
 #define PCI_DMA_FROMDEVICE	2
 #define PCI_DMA_NONE		3
 
+#define PCI_DMA_64BIT	0xffffffffffffffffULL
+#define PCI_DMA_32BIT	0x00000000ffffffffULL
+
 #define DEVICE_COUNT_COMPATIBLE	4
 #define DEVICE_COUNT_RESOURCE	12
 
author
#2 lore raw

ChangeSet 1.1692.3.1, 2004/03/26 16:11:41-08:00, [email protected]

PCI: add ability to access pci extended config space for PCI Express devices

Patch originally written by Intel, cleaned up and made sane by Matthew Wilcox <[email protected]> and then tweaked a bit more by me.

Quoted 1 line

From Matt's original email:

- Add cfg_size to struct pci_dev.
- Use it in sysfs and procfs.
- Introduce pci_find_ext_capability() for finding extended capabilities.
- Change the PCI_X_STATUS defines to match the spec (mea culpa there).
- Add defines for the extended capabilities.

 drivers/pci/pci-sysfs.c |   29 ++++++++++----
 drivers/pci/pci.c       |   58 ++++++++++++++++++++++++----
 drivers/pci/probe.c     |   40 +++++++++++++++++++
 drivers/pci/proc.c      |   26 ++++++------
 include/linux/pci.h     |   99 ++++++++++++++++++++++++++++++++++++++++++------
 5 files changed, 212 insertions(+), 40 deletions(-)
drivers/pci/pci-sysfs.c +22 -7
diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
@@ -1,8 +1,8 @@
 /*
  * drivers/pci/pci-sysfs.c
  *
- * (C) Copyright 2002 Greg Kroah-Hartman
- * (C) Copyright 2002 IBM Corp.
+ * (C) Copyright 2002-2004 Greg Kroah-Hartman <[email protected]>
+ * (C) Copyright 2002-2004 IBM Corp.
  * (C) Copyright 2003 Matthew Wilcox
  * (C) Copyright 2003 Hewlett-Packard
  *
@@ -71,7 +71,7 @@
 
 	/* Several chips lock up trying to read undefined config space */
 	if (capable(CAP_SYS_ADMIN)) {
-		size = 256;
+		size = dev->cfg_size;
 	} else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
 		size = 128;
 	}
@@ -123,10 +123,10 @@
 	unsigned int size = count;
 	loff_t init_off = off;
 
-	if (off > 256)
+	if (off > dev->cfg_size)
 		return 0;
-	if (off + count > 256) {
-		size = 256 - off;
+	if (off + count > dev->cfg_size) {
+		size = dev->cfg_size - off;
 		count = size;
 	}
 
@@ -167,6 +167,17 @@
 	.write = pci_write_config,
 };
 
+static struct bin_attribute pcie_config_attr = {
+	.attr =	{
+		.name = "config",
+		.mode = S_IRUGO | S_IWUSR,
+		.owner = THIS_MODULE,
+	},
+	.size = 4096,
+	.read = pci_read_config,
+	.write = pci_write_config,
+};
+
 void pci_create_sysfs_dev_files (struct pci_dev *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -179,7 +190,11 @@
 	device_create_file (dev, &dev_attr_class);
 	device_create_file (dev, &dev_attr_irq);
 	device_create_file (dev, &dev_attr_resource);
-	sysfs_create_bin_file(&dev->kobj, &pci_config_attr);
+
+	if (pdev->cfg_size < 4096)
+		sysfs_create_bin_file(&dev->kobj, &pci_config_attr);
+	else
+		sysfs_create_bin_file(&dev->kobj, &pcie_config_attr);
 
 	/* add platform-specific attributes */
 	pcibios_add_platform_entries(pdev);
drivers/pci/pci.c +50 -8

77 lines not on this page · raw message

drivers/pci/probe.c +40 -0
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
@@ -18,6 +18,8 @@
 
 #define CARDBUS_LATENCY_TIMER	176	/* secondary latency timer */
 #define CARDBUS_RESERVE_BUSNR	3
+#define PCI_CFG_SPACE_SIZE	256
+#define PCI_CFG_SPACE_EXP_SIZE	4096
 
 /* Ugh.  Need to stop exporting this to modules. */
 LIST_HEAD(pci_root_buses);
@@ -530,6 +532,43 @@
 	kfree(pci_dev);
 }
 
+/**
+ * pci_cfg_space_size - get the configuration space size of the PCI device.
+ *
+ * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices
+ * have 4096 bytes.  Even if the device is capable, that doesn't mean we can
+ * access it.  Maybe we don't have a way to generate extended config space
+ * accesses, or the device is behind a reverse Express bridge.  So we try
+ * reading the dword at 0x100 which must either be 0 or a valid extended
+ * capability header.
+ */
+static int pci_cfg_space_size(struct pci_dev *dev)
+{
+	int pos;
+	u32 status;
+
+	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (!pos) {
+		pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+		if (!pos)
+			goto fail;
+
+		pci_read_config_dword(dev, pos + PCI_X_STATUS, &status);
+		if (!(status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ)))
+			goto fail;
+	}
+
+	if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
+		goto fail;
+	if (status == 0xffffffff)
+		goto fail;
+
+	return PCI_CFG_SPACE_EXP_SIZE;
+
+ fail:
+	return PCI_CFG_SPACE_SIZE;
+}
+
 /*
  * Read the config data for a PCI device, sanity-check it
  * and fill in the dev structure...
@@ -566,6 +605,7 @@
 	dev->multifunction = !!(hdr_type & 0x80);
 	dev->vendor = l & 0xffff;
 	dev->device = (l >> 16) & 0xffff;
+	dev->cfg_size = pci_cfg_space_size(dev);
 
 	/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
 	   set this higher, assuming the system even supports it.  */
drivers/pci/proc.c +13 -13
diff -Nru a/drivers/pci/proc.c b/drivers/pci/proc.c
@@ -16,16 +16,15 @@
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 
-#define PCI_CFG_SPACE_SIZE 256
-
 static int proc_initialized;	/* = 0 */
 
 static loff_t
 proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
 {
 	loff_t new = -1;
+	struct inode *inode = file->f_dentry->d_inode;
 
-	down(&file->f_dentry->d_inode->i_sem);
+	down(&inode->i_sem);
 	switch (whence) {
 	case 0:
 		new = off;
@@ -34,14 +33,14 @@
 		new = file->f_pos + off;
 		break;
 	case 2:
-		new = PCI_CFG_SPACE_SIZE + off;
+		new = inode->i_size + off;
 		break;
 	}
-	if (new < 0 || new > PCI_CFG_SPACE_SIZE)
+	if (new < 0 || new > inode->i_size)
 		new = -EINVAL;
 	else
 		file->f_pos = new;
-	up(&file->f_dentry->d_inode->i_sem);
+	up(&inode->i_sem);
 	return new;
 }
 
@@ -61,7 +60,7 @@
 	 */
 
 	if (capable(CAP_SYS_ADMIN))
-		size = PCI_CFG_SPACE_SIZE;
+		size = dev->cfg_size;
 	else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
 		size = 128;
 	else
@@ -134,14 +133,15 @@
 	const struct proc_dir_entry *dp = PDE(ino);
 	struct pci_dev *dev = dp->data;
 	int pos = *ppos;
+	int size = dev->cfg_size;
 	int cnt;
 
-	if (pos >= PCI_CFG_SPACE_SIZE)
+	if (pos >= size)
 		return 0;
-	if (nbytes >= PCI_CFG_SPACE_SIZE)
-		nbytes = PCI_CFG_SPACE_SIZE;
-	if (pos + nbytes > PCI_CFG_SPACE_SIZE)
-		nbytes = PCI_CFG_SPACE_SIZE - pos;
+	if (nbytes >= size)
+		nbytes = size;
+	if (pos + nbytes > size)
+		nbytes = size - pos;
 	cnt = nbytes;
 
 	if (!access_ok(VERIFY_READ, buf, cnt))
@@ -403,7 +403,7 @@
 		return -ENOMEM;
 	e->proc_fops = &proc_bus_pci_operations;
 	e->data = dev;
-	e->size = PCI_CFG_SPACE_SIZE;
+	e->size = dev->cfg_size;
 
 	return 0;
 }
include/linux/pci.h +87 -12

123 lines not on this page · raw message

author
#3 lore raw

ChangeSet 1.1692.3.3, 2004/03/26 16:31:44-08:00, [email protected]

[PATCH] PCI: Updates for PCI Express hot-plug driver

 drivers/pci/hotplug/pciehp_hpc.c      |   91 +++++++++++++++++++++++++++-------
 drivers/pci/hotplug/pciehp_pci.c      |    2 
 drivers/pci/hotplug/shpchp_hpc.c      |   11 +---
 drivers/pci/hotplug/shpchprm_acpi.c   |    3 -
 drivers/pci/hotplug/shpchprm_legacy.c |   30 -----------
 drivers/pci/pci.h                     |    2 
 drivers/pci/quirks.c                  |   11 ++++
 include/linux/pci_ids.h               |    1 
 8 files changed, 95 insertions(+), 56 deletions(-)
drivers/pci/hotplug/pciehp_hpc.c +74 -17
diff -Nru a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
@@ -37,6 +37,7 @@
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <asm/system.h>
+#include "../pci.h"
 #include "pciehp.h"
 
 #ifdef DEBUG
@@ -315,12 +316,13 @@
 		dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
 	}
 
-	retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd);
+	dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
+	retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE);
 	if (retval) {
 		err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
 		return retval;
 	}
-	dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
+	dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd | CMD_CMPL_INTR_ENABLE);
 	dbg("%s : Exit\n", __FUNCTION__);
 
 	DBG_LEAVE_ROUTINE 
@@ -918,13 +920,32 @@
 			return IRQ_NONE;;
 		}
 
-		temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x00;
+		dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__);
+		dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
+		temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
 
 		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
 		if (rc) {
 			err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
-			return IRQ_NONE;;
+			return IRQ_NONE;
+		}
+		dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
+		
+		rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+		if (rc) {
+			err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+			return IRQ_NONE;
+		}
+		dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); 
+		
+		/* Clear command complete interrupt caused by this write */
+		temp_word = 0x1f;
+		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+		if (rc) {
+			err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
+			return IRQ_NONE;
 		}
+		dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
 	}
 	
 	if (intr_loc & CMD_COMPLETED) {
@@ -949,7 +970,7 @@
 			hp_slot, php_ctlr->callback_instance_id);
 
 	/* Clear all events after serving them */
-	temp_word = slot_status | 0xff;
+	temp_word = 0x1F;
 	rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
 	if (rc) {
 		err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
@@ -963,6 +984,8 @@
 			return IRQ_NONE;
 		}
 
+		dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
+		dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
 		temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
 
 		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
@@ -970,6 +993,23 @@
 			err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
 			return IRQ_NONE;
 		}
+		dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); 	
+	
+		rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+		if (rc) {
+			err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+			return IRQ_NONE;
+		}
+		dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); 
+		
+		/* Clear command complete interrupt caused by this write */
+		temp_word = 0x1F;
+		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+		if (rc) {
+			err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
+			return IRQ_NONE;
+		}
+		dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word); 
 	}
 	
 	return IRQ_HANDLED;
@@ -1330,7 +1370,7 @@
 	}
 
 	dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
-	temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x00;
+	temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
 
 	rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
 	if (rc) {
@@ -1346,12 +1386,13 @@
 	}
 	dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
 
-	rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+	temp_word = 0x1F; /* Clear all events */
+	rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
 	if (rc) {
 		err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
-	dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
+	dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
 
 	if (pciehp_poll_mode)  {/* Install interrupt polling code */
 		/* Install and start the interrupt polling timer */
@@ -1359,15 +1400,16 @@
 		start_int_poll_timer( php_ctlr, 10 );   /* start with 10 second delay */
 	} else {
 		/* Installs the interrupt handler */
-#ifdef CONFIG_PCI_USE_VECTOR 
-		rc = pci_enable_msi(pdev);
-		if (rc) {
-			err("Can't get msi for the hotplug controller\n");
-			dbg("%s: rc = %x\n", __FUNCTION__, rc);
-			goto abort_free_ctlr;
+		dbg("%s: pciehp_msi_quirk = %x\n", __FUNCTION__, pciehp_msi_quirk);
+		if (!pciehp_msi_quirk) {
+			rc = pci_enable_msi(pdev);
+			if (rc) {
+				info("Can't get msi for the hotplug controller\n");
+				info("Use INTx for the hotplug controller\n");
+				dbg("%s: rc = %x\n", __FUNCTION__, rc);
+			} else 
+				php_ctlr->irq = pdev->irq;
 		}
-		php_ctlr->irq = pdev->irq;
-#endif		
 		rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
 		dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
 		if (rc) {
@@ -1384,7 +1426,7 @@
 	dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
 
 	intr_enable = ATTN_BUTTN_ENABLE | PWR_FAULT_DETECT_ENABLE | MRL_DETECT_ENABLE |
-					PRSN_DETECT_ENABLE | CMD_CMPL_INTR_ENABLE;
+					PRSN_DETECT_ENABLE;
 
 	temp_word = (temp_word & ~intr_enable) | intr_enable; 
 
@@ -1402,6 +1444,21 @@
 		goto abort_free_ctlr;
 	}
 	dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
+	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+	if (rc) {
+		err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+		goto abort_free_ctlr;
+	}
+	dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, 
+		SLOT_STATUS, slot_status);
+	
+	temp_word =  0x1F; /* Clear all events */
+	rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+	if (rc) {
+		err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
+		goto abort_free_ctlr;
+	}
+	dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
 	
 	/*  Add this HPC instance into the HPC list */
 	spin_lock(&list_lock);
drivers/pci/hotplug/pciehp_pci.c +0 -2
diff -Nru a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
@@ -192,7 +192,6 @@
 	for (device = FirstSupported; device <= LastSupported; device++) {
 		ID = 0xFFFFFFFF;
 		rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
-		dbg("%s: ID = %x\n", __FUNCTION__, ID);
 
 		if (ID != 0xFFFFFFFF) {	  /*  device in slot */
 			dbg("%s: ID = %x\n", __FUNCTION__, ID);
@@ -325,7 +324,6 @@
 			new_slot->presence_save = 0;
 			new_slot->switch_save = 0;
 		}
-		dbg("%s: End of For loop\n", __FUNCTION__);
 	} 			/* End of FOR loop */
 
 	dbg("%s: Exit\n", __FUNCTION__);
drivers/pci/hotplug/shpchp_hpc.c +5 -6
diff -Nru a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
@@ -1441,6 +1441,7 @@
 			err("%s : shpc_cap_offset == 0\n", __FUNCTION__);
 			goto abort_free_ctlr;
 		}
+		dbg("%s: shpc_cap_offset = %x\n", __FUNCTION__, shpc_cap_offset);	
 	
 		rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , BASE_OFFSET);
 		if (rc) {
@@ -1547,15 +1548,13 @@
 		start_int_poll_timer( php_ctlr, 10 );   /* start with 10 second delay */
 	} else {
 		/* Installs the interrupt handler */
-#ifdef CONFIG_PCI_USE_VECTOR 
 		rc = pci_enable_msi(pdev);
 		if (rc) {
-			err("Can't get msi for the hotplug controller\n");
+			info("Can't get msi for the hotplug controller\n");
+			info("Use INTx for the hotplug controller\n");
 			dbg("%s: rc = %x\n", __FUNCTION__, rc);
-			goto abort_free_ctlr;
-		}
-		php_ctlr->irq = pdev->irq;
-#endif
+		} else
+			php_ctlr->irq = pdev->irq;
 		
 		rc = request_irq(php_ctlr->irq, shpc_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
 		dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
drivers/pci/hotplug/shpchprm_acpi.c +2 -1
diff -Nru a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
@@ -1267,7 +1267,8 @@
 int shpchprm_print_pirt(void)
 {
 	dbg("SHPCHPRM ACPI Slots\n");
-	print_acpi_resources (acpi_bridges_head);
+	if (acpi_bridges_head)
+		print_acpi_resources (acpi_bridges_head);
 	return 0;
 }
 
drivers/pci/hotplug/shpchprm_legacy.c +0 -30
diff -Nru a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
@@ -96,23 +96,6 @@
 	return fp;
 }
 
-#if link_available
-/*
- *  Links available memory, IO, and IRQ resources for programming
- *  devices which may be added to the system
- *
- *  Returns 0 if success
- */
-static int
-link_available_resources (
-	struct controller *ctrl,
-	struct pci_func *func,
-	int index )
-{
-	return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD);
-}
-#endif
-
 /*
  * shpchprm_find_available_resources
  *
@@ -345,19 +328,6 @@
 			}
 		}
 
-#if link_available
-		++index;
-
-		while (index < 8) {
-			if (((func = shpchp_slot_find(primary_bus, dev_func >> 3, index)) != NULL) && populated_slot)
-				rc = link_available_resources(ctrl, func, index);
-			
-			if (rc)
-				break;
-
-			++index;
-		}
-#endif
 		i--;
 		one_slot += sizeof(struct slot_rt);
 	}
drivers/pci/pci.h +2 -0
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
@@ -60,3 +60,5 @@
 
 /* Lock for read/write access to pci device and bus lists */
 extern spinlock_t pci_bus_lock;
+
+extern int pciehp_msi_quirk;
drivers/pci/quirks.c +11 -0
diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c
@@ -868,6 +868,13 @@
 }
 #endif /* CONFIG_SCSI_SATA */
 
+int pciehp_msi_quirk;
+
+static void __devinit quirk_pciehp_msi(struct pci_dev *pdev)
+{
+	pciehp_msi_quirk = 1;
+}
+
 /*
  *  The main table of quirks.
  *
@@ -984,6 +991,8 @@
 	  quirk_intel_ide_combined },
 #endif /* CONFIG_SCSI_SATA */
 
+	{ PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_SMCH,	quirk_pciehp_msi },
+
 	{ 0 }
 };
 
@@ -1008,3 +1017,5 @@
 	pci_do_fixups(dev, pass, pcibios_fixups);
 	pci_do_fixups(dev, pass, pci_fixups);
 }
+
+EXPORT_SYMBOL(pciehp_msi_quirk);
include/linux/pci_ids.h +1 -0
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
@@ -2073,6 +2073,7 @@
 #define PCI_DEVICE_ID_INTEL_82830_CGC	0x3577
 #define PCI_DEVICE_ID_INTEL_82855GM_HB	0x3580
 #define PCI_DEVICE_ID_INTEL_82855GM_IG	0x3582
+#define PCI_DEVICE_ID_INTEL_SMCH	0x3590
 #define PCI_DEVICE_ID_INTEL_80310	0x530d
 #define PCI_DEVICE_ID_INTEL_82371SB_0	0x7000
 #define PCI_DEVICE_ID_INTEL_82371SB_1	0x7010
author
#4 lore raw

ChangeSet 1.1692.3.4, 2004/03/26 16:32:21-08:00, [email protected]

[PATCH] PCI Hotplug: Don't up() twice in acpiphp

On the error path, we currently try to up() a semaphore twice. There was also a typo in an error message.

 drivers/pci/hotplug/acpiphp_glue.c |   38 +++++++++++++++++--------------------
 1 files changed, 18 insertions(+), 20 deletions(-)
drivers/pci/hotplug/acpiphp_glue.c +18 -20
diff -Nru a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1243,40 +1243,38 @@
 
 /**
  * acpiphp_check_bridge - re-enumerate devices
+ *
+ * Iterate over all slots under this bridge and make sure that if a
+ * card is present they are enabled, and if not they are disabled.
  */
 int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
 {
 	struct acpiphp_slot *slot;
-	unsigned int sta;
 	int retval = 0;
 	int enabled, disabled;
 
 	enabled = disabled = 0;
 
 	for (slot = bridge->slots; slot; slot = slot->next) {
-		sta = get_slot_status(slot);
+		unsigned int status = get_slot_status(slot);
 		if (slot->flags & SLOT_ENABLED) {
-			/* if enabled but not present, disable */
-			if (sta != ACPI_STA_ALL) {
-				retval = acpiphp_disable_slot(slot);
-				if (retval) {
-					err("Error occurred in enabling\n");
-					up(&slot->crit_sect);
-					goto err_exit;
-				}
-				disabled++;
+			if (status == ACPI_STA_ALL)
+				continue;
+			retval = acpiphp_disable_slot(slot);
+			if (retval) {
+				err("Error occurred in disabling\n");
+				goto err_exit;
 			}
+			disabled++;
 		} else {
-			/* if disabled but present, enable */
-			if (sta == ACPI_STA_ALL) {
-				retval = acpiphp_enable_slot(slot);
-				if (retval) {
-					err("Error occurred in enabling\n");
-					up(&slot->crit_sect);
-					goto err_exit;
-				}
-				enabled++;
+			if (status != ACPI_STA_ALL)
+				continue;
+			retval = acpiphp_enable_slot(slot);
+			if (retval) {
+				err("Error occurred in enabling\n");
+				goto err_exit;
 			}
+			enabled++;
 		}
 	}
 
author
#5 lore raw

ChangeSet 1.1692.3.5, 2004/03/26 16:32:52-08:00, [email protected]

[PATCH] PCI Hotplug: Rewrite acpiphp detect_used_resource

There are two unrelated problems in acpiphp that are fixed by this patch. First, acpiphp can be a module, so it is unsafe to probe the BARs of each device while it initialises -- the device may be active at the time. Second, it does not know about PCI-PCI bridge registers and so it reads garbage for the last 4 registers of the PCI-PCI bridge card and doesn't take into account the ranges that are forwarded by the bridge.

This patch avoids all that by using the struct resources embedded in the pci_dev. Note that we no longer need to recurse as all the devices on the other side of a PCI-PCI bridge have their resources entirely contained within the PCI-PCI bridge's ranges.

 drivers/pci/hotplug/acpiphp_pci.c |  110 ++++++++------------------------------
 1 files changed, 26 insertions(+), 84 deletions(-)
drivers/pci/hotplug/acpiphp_pci.c +26 -84
diff -Nru a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c
@@ -198,106 +198,42 @@
 /* detect_used_resource - subtract resource under dev from bridge */
 static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
 {
-	u32 bar, len;
-	u64 base;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
 	int count;
-	struct pci_resource *res;
 
 	dbg("Device %s\n", pci_name(dev));
 
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-		pci_read_config_dword(dev, address[count], &bar);
+	for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) {
+		struct pci_resource *res;
+		struct pci_resource **head;
+		unsigned long base = dev->resource[count].start;
+		unsigned long len = dev->resource[count].end - base + 1;
+		unsigned long flags = dev->resource[count].flags;
 
-		if (!bar)	/* This BAR is not implemented */
+		if (!flags)
 			continue;
 
-		pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
-		pci_read_config_dword(dev, address[count], &len);
+		dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base,
+				base + len - 1, flags);
 
-		if (len & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-			base = bar & 0xFFFFFFFC;
-			len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
-			len = len & ~(len - 1);
-
-			dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
-
-			spin_lock(&bridge->res_lock);
-			res = acpiphp_get_resource_with_base(&bridge->io_head, base, len);
-			spin_unlock(&bridge->res_lock);
-			if (res)
-				kfree(res);
+		if (flags & IORESOURCE_IO) {
+			head = &bridge->io_head;
+		} else if (flags & IORESOURCE_PREFETCH) {
+			head = &bridge->p_mem_head;
 		} else {
-			/* This is Memory */
-			base = bar & 0xFFFFFFF0;
-			if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
-					dbg("prefetch mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource_with_base(&bridge->p_mem_head, base, len);
-				spin_unlock(&bridge->res_lock);
-				if (res)
-					kfree(res);
-			} else {
-				/* regular memory */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					dbg("mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource_with_base(&bridge->mem_head, base, len);
-				spin_unlock(&bridge->res_lock);
-				if (res)
-					kfree(res);
-			}
+			head = &bridge->mem_head;
 		}
 
-		pci_write_config_dword(dev, address[count], bar);
+		spin_lock(&bridge->res_lock);
+		res = acpiphp_get_resource_with_base(head, base, len);
+		spin_unlock(&bridge->res_lock);
+		if (res)
+			kfree(res);
 	}
 
 	return 0;
 }
 
 
-/* detect_pci_resource_bus - subtract resource under pci_bus */
-static void detect_used_resource_bus(struct acpiphp_bridge *bridge, struct pci_bus *bus)
-{
-	struct list_head *l;
-	struct pci_dev *dev;
-
-	list_for_each (l, &bus->devices) {
-		dev = pci_dev_b(l);
-		detect_used_resource(bridge, dev);
-		/* XXX recursive call */
-		if (dev->subordinate)
-			detect_used_resource_bus(bridge, dev->subordinate);
-	}
-}
-
-
 /**
  * acpiphp_detect_pci_resource - detect resources under bridge
  * @bridge: detect all resources already used under this bridge
@@ -306,7 +242,13 @@
  */
 int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
 {
-	detect_used_resource_bus(bridge, bridge->pci_bus);
+	struct list_head *l;
+	struct pci_dev *dev;
+
+	list_for_each (l, &bridge->pci_bus->devices) {
+		dev = pci_dev_b(l);
+		detect_used_resource(bridge, dev);
+	}
 
 	return 0;
 }
author
#6 lore raw

ChangeSet 1.1692.3.6, 2004/03/30 17:24:37-08:00, [email protected]

Cset exclude: [email protected]|ChangeSet|20040323051558|61282

 Documentation/DMA-mapping.txt |   16 ++++++++--------
 drivers/net/e1000/e1000.h     |    2 ++
 drivers/net/ixgb/ixgb.h       |    2 ++
 include/linux/pci.h           |    3 ---
 4 files changed, 12 insertions(+), 11 deletions(-)
Documentation/DMA-mapping.txt +8 -8
diff -Nru a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
@@ -132,7 +132,7 @@
 The standard 32-bit addressing PCI device would do something like
 this:
 
-	if (pci_set_dma_mask(pdev, PCI_DMA_32BIT)) {
+	if (pci_set_dma_mask(pdev, 0xffffffff)) {
 		printk(KERN_WARNING
 		       "mydev: No suitable DMA available.\n");
 		goto ignore_this_device;
@@ -151,9 +151,9 @@
 
 	int using_dac;
 
-	if (!pci_set_dma_mask(pdev, PCI_DMA_64BIT)) {
+	if (!pci_set_dma_mask(pdev, 0xffffffffffffffff)) {
 		using_dac = 1;
-	} else if (!pci_set_dma_mask(pdev, PCI_DMA_32BIT)) {
+	} else if (!pci_set_dma_mask(pdev, 0xffffffff)) {
 		using_dac = 0;
 	} else {
 		printk(KERN_WARNING
@@ -166,14 +166,14 @@
 
 	int using_dac, consistent_using_dac;
 
-	if (!pci_set_dma_mask(pdev, PCI_DMA_64BIT)) {
+	if (!pci_set_dma_mask(pdev, 0xffffffffffffffff)) {
 		using_dac = 1;
 	   	consistent_using_dac = 1;
-		pci_set_consistent_dma_mask(pdev, PCI_DMA_64BIT);
-	} else if (!pci_set_dma_mask(pdev, PCI_DMA_32BIT)) {
+		pci_set_consistent_dma_mask(pdev, 0xffffffffffffffff)
+	} else if (!pci_set_dma_mask(pdev, 0xffffffff)) {
 		using_dac = 0;
 		consistent_using_dac = 0;
-		pci_set_consistent_dma_mask(pdev, PCI_DMA_32BIT);
+		pci_set_consistent_dma_mask(pdev, 0xffffffff)
 	} else {
 		printk(KERN_WARNING
 		       "mydev: No suitable DMA available.\n");
@@ -215,7 +215,7 @@
 
 Here is pseudo-code showing how this might be done:
 
-	#define PLAYBACK_ADDRESS_BITS	PCI_DMA_32BIT
+	#define PLAYBACK_ADDRESS_BITS	0xffffffff
 	#define RECORD_ADDRESS_BITS	0x00ffffff
 
 	struct my_sound_card *card;
drivers/net/e1000/e1000.h +2 -0
diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
@@ -74,6 +74,8 @@
 #define BAR_0		0
 #define BAR_1		1
 #define BAR_5		5
+#define PCI_DMA_64BIT	0xffffffffffffffffULL
+#define PCI_DMA_32BIT	0x00000000ffffffffULL
 
 
 struct e1000_adapter;
drivers/net/ixgb/ixgb.h +2 -0
diff -Nru a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
@@ -65,6 +65,8 @@
 #define BAR_0           0
 #define BAR_1           1
 #define BAR_5           5
+#define PCI_DMA_64BIT   0xffffffffffffffffULL
+#define PCI_DMA_32BIT   0x00000000ffffffffULL
 
 #include "ixgb_hw.h"
 #include "ixgb_ee.h"
include/linux/pci.h +0 -3
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
@@ -433,9 +433,6 @@
 #define PCI_DMA_FROMDEVICE	2
 #define PCI_DMA_NONE		3
 
-#define PCI_DMA_64BIT	0xffffffffffffffffULL
-#define PCI_DMA_32BIT	0x00000000ffffffffULL
-
 #define DEVICE_COUNT_COMPATIBLE	4
 #define DEVICE_COUNT_RESOURCE	12
 
author
#7 lore raw

ChangeSet 1.1692.3.7, 2004/03/30 17:26:44-08:00, [email protected]

[PATCH] PCI: add DMA_{64,32}BIT constants

Quoted 5 lines · On Tue, 23 Mar 2004 00:23:05 -0500 Jeff Garzik <[email protected]> wrote:
Quoted 5 lines

Yeah well... in the intervening time, somebody on IRC commented

"so what is so PCI-specific about those constants?"

They probably ought to be DMA_{32,64}BIT_MASK or somesuch.

Here's an updated patch, applies to 2.6.5-rc2-bk9. I left the DMA_xxBIT_MASK defines in linux/pci.h, although they aren't necessarily PCI-specific. Would we prefer to have them in linux/dma-mapping.h ?

 Documentation/DMA-mapping.txt  |   16 ++++++++--------
 drivers/net/e1000/e1000.h      |    2 --
 drivers/net/e1000/e1000_main.c |    4 ++--
 drivers/net/ixgb/ixgb.h        |    2 --
 drivers/net/ixgb/ixgb_main.c   |    4 ++--
 include/linux/pci.h            |    3 +++
 6 files changed, 15 insertions(+), 16 deletions(-)
Documentation/DMA-mapping.txt +8 -8
diff -Nru a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
@@ -132,7 +132,7 @@
 The standard 32-bit addressing PCI device would do something like
 this:
 
-	if (pci_set_dma_mask(pdev, 0xffffffff)) {
+	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 		printk(KERN_WARNING
 		       "mydev: No suitable DMA available.\n");
 		goto ignore_this_device;
@@ -151,9 +151,9 @@
 
 	int using_dac;
 
-	if (!pci_set_dma_mask(pdev, 0xffffffffffffffff)) {
+	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 		using_dac = 1;
-	} else if (!pci_set_dma_mask(pdev, 0xffffffff)) {
+	} else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 		using_dac = 0;
 	} else {
 		printk(KERN_WARNING
@@ -166,14 +166,14 @@
 
 	int using_dac, consistent_using_dac;
 
-	if (!pci_set_dma_mask(pdev, 0xffffffffffffffff)) {
+	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 		using_dac = 1;
 	   	consistent_using_dac = 1;
-		pci_set_consistent_dma_mask(pdev, 0xffffffffffffffff)
-	} else if (!pci_set_dma_mask(pdev, 0xffffffff)) {
+		pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+	} else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 		using_dac = 0;
 		consistent_using_dac = 0;
-		pci_set_consistent_dma_mask(pdev, 0xffffffff)
+		pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
 	} else {
 		printk(KERN_WARNING
 		       "mydev: No suitable DMA available.\n");
@@ -215,7 +215,7 @@
 
 Here is pseudo-code showing how this might be done:
 
-	#define PLAYBACK_ADDRESS_BITS	0xffffffff
+	#define PLAYBACK_ADDRESS_BITS	DMA_32BIT_MASK
 	#define RECORD_ADDRESS_BITS	0x00ffffff
 
 	struct my_sound_card *card;
drivers/net/e1000/e1000.h +0 -2
diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
@@ -74,8 +74,6 @@
 #define BAR_0		0
 #define BAR_1		1
 #define BAR_5		5
-#define PCI_DMA_64BIT	0xffffffffffffffffULL
-#define PCI_DMA_32BIT	0x00000000ffffffffULL
 
 
 struct e1000_adapter;
drivers/net/e1000/e1000_main.c +2 -2
diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
@@ -383,10 +383,10 @@
 	if((err = pci_enable_device(pdev)))
 		return err;
 
-	if(!(err = pci_set_dma_mask(pdev, PCI_DMA_64BIT))) {
+	if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
 		pci_using_dac = 1;
 	} else {
-		if((err = pci_set_dma_mask(pdev, PCI_DMA_32BIT))) {
+		if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
 			E1000_ERR("No usable DMA configuration, aborting\n");
 			return err;
 		}
drivers/net/ixgb/ixgb.h +0 -2
diff -Nru a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
@@ -65,8 +65,6 @@
 #define BAR_0           0
 #define BAR_1           1
 #define BAR_5           5
-#define PCI_DMA_64BIT   0xffffffffffffffffULL
-#define PCI_DMA_32BIT   0x00000000ffffffffULL
 
 #include "ixgb_hw.h"
 #include "ixgb_ee.h"
drivers/net/ixgb/ixgb_main.c +2 -2
diff -Nru a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
@@ -308,10 +308,10 @@
 		return i;
 	}
 
-	if (!(i = pci_set_dma_mask(pdev, PCI_DMA_64BIT))) {
+	if (!(i = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
 		pci_using_dac = 1;
 	} else {
-		if ((i = pci_set_dma_mask(pdev, PCI_DMA_32BIT))) {
+		if ((i = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
 			IXGB_ERR("No usable DMA configuration, aborting\n");
 			return i;
 		}
include/linux/pci.h +3 -0
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
@@ -433,6 +433,9 @@
 #define PCI_DMA_FROMDEVICE	2
 #define PCI_DMA_NONE		3
 
+#define DMA_64BIT_MASK	0xffffffffffffffffULL
+#define DMA_32BIT_MASK	0x00000000ffffffffULL
+
 #define DEVICE_COUNT_COMPATIBLE	4
 #define DEVICE_COUNT_RESOURCE	12
 
author
#8 lore raw

ChangeSet 1.1692.3.8, 2004/03/31 14:53:59-08:00, [email protected]

[PATCH] PCI: move DMA_nnBIT_MASK to linux/dma-mapping.h

 include/linux/dma-mapping.h |    3 +++
 include/linux/pci.h         |    3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)
include/linux/dma-mapping.h +3 -0
diff -Nru a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
@@ -10,6 +10,9 @@
 	DMA_NONE = 3,
 };
 
+#define DMA_64BIT_MASK	0xffffffffffffffffULL
+#define DMA_32BIT_MASK	0x00000000ffffffffULL
+
 #include <asm/dma-mapping.h>
 
 /* Backwards compat, remove in 2.7.x */
include/linux/pci.h +0 -3
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
@@ -433,9 +433,6 @@
 #define PCI_DMA_FROMDEVICE	2
 #define PCI_DMA_NONE		3
 
-#define DMA_64BIT_MASK	0xffffffffffffffffULL
-#define DMA_32BIT_MASK	0x00000000ffffffffULL
-
 #define DEVICE_COUNT_COMPATIBLE	4
 #define DEVICE_COUNT_RESOURCE	12
 
author
#9 lore raw

ChangeSet 1.1692.3.9, 2004/03/31 14:55:47-08:00, [email protected]

[PATCH] PCI Hotplug: RPA PCI Hotplug - redundant free

Please commit the following patch, which removes a redundant call to a cleanup function from an error path of the module init code.

 drivers/pci/hotplug/rpaphp_pci.c |    1 -
 1 files changed, 1 deletion(-)
drivers/pci/hotplug/rpaphp_pci.c +0 -1
diff -Nru a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
@@ -304,7 +304,6 @@
 	if (slot->hotplug_slot->info->adapter_status == NOT_VALID) {
 		dbg("%s: NOT_VALID: skip dn->full_name=%s\n",
 		    __FUNCTION__, slot->dn->full_name);
-		dealloc_slot_struct(slot);
 		return (-1);
 	}
 	return (0);
author
#10 lore raw

ChangeSet 1.1692.3.10, 2004/03/31 14:57:52-08:00, [email protected]

[PATCH] PCI: Allow arch-specific pci_set_dma_mask and friends

The patch provides the ability for architectures to have custom implementations of pci_set_dma_mask() and friends (dac_set_dma_mask and set_consistent_dma_mask). The reason I need this is b/c I have a chipset (Intel ARM IXP425) that has a broken PCI interface that only allows PCI dma to/from the bottom 64MB of system memory. To get around this limitation, I trap a custom dma-mapping implementation that bounces buffers outside the 64MB window. At device discover time, my custom platform_notify() function gets called and it sets the dma_mask to (64MB-1) and in ARM's dma-mapping code, I check for dma_mask != 0xffffffff and if that is true, I call the special bounce helpers. This works great except that certain drivers (e100, ide-pci) call pci_set_dma_mask() with 0xffffffff and the generic implementation only allows for the architecture-defined pci_dma_supported() to return true or false. There is no method for the architecture to tell the PCI layer "I can't set the mask to 0xffffffff, but I can set it to this other value" and there is no way to pass that back to the driver. What this means is that if I have pci_set_dma_supported() return failure on full 32-bit DMA, the driver will not initialize the card; however, if I return true, pci_set_dma_mask() will set the dma mask to full 32-bits and I can no longer trap and will have buffers that are not dma-able and cause PCI master aborts. Both of those are not acceptable. IMHO, the driver shouldn't care if the architecture has to bounce DMA outside of 64MB and since this is not something most architectures have to worry about, the easiest way to get around the issue is by allowing custom pci_set_dma_mask() for arches that need it but keeping the generic implementation for those that do not. In my case, it simply returns 0 to the driver but keeps the device mask set to 64MB-1 so I can trap.

 drivers/pci/pci.c |    5 +++++
 1 files changed, 5 insertions(+)
drivers/pci/pci.c +5 -0
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
@@ -700,6 +700,10 @@
 	}
 }
 
+#ifndef HAVE_ARCH_PCI_SET_DMA_MASK
+/*
+ * These can be overridden by arch-specific implementations
+ */
 int
 pci_set_dma_mask(struct pci_dev *dev, u64 mask)
 {
@@ -732,6 +736,7 @@
 
 	return 0;
 }
+#endif
      
 static int __devinit pci_init(void)
 {
author
#11 lore raw

ChangeSet 1.1692.3.11, 2004/04/07 16:10:06-07:00, [email protected]

[PATCH] PCI Hotplug: Fix interpretation of 0/1 for MRL in SHPC & PCI-E hot-plug

This patch contains fixes for interpretation of 0/1 for MRL to match pcihpview, bus speed definition in shpchp_hpc.c etc.

 drivers/pci/hotplug/pci_hotplug.h |    2 +-
 drivers/pci/hotplug/pciehp_ctrl.c |    6 +++---
 drivers/pci/hotplug/shpchp_ctrl.c |   10 +++++-----
 drivers/pci/hotplug/shpchp_hpc.c  |   15 ++++++++-------
 4 files changed, 17 insertions(+), 16 deletions(-)
drivers/pci/hotplug/pci_hotplug.h +1 -1
diff -Nru a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h
@@ -43,7 +43,7 @@
 	PCI_SPEED_100MHz_PCIX_266	= 0x0a,
 	PCI_SPEED_133MHz_PCIX_266	= 0x0b,
 	PCI_SPEED_66MHz_PCIX_533	= 0x11,
-	PCI_SPEED_100MHz_PCIX_533	= 0X12,
+	PCI_SPEED_100MHz_PCIX_533	= 0x12,
 	PCI_SPEED_133MHz_PCIX_533	= 0x13,
 	PCI_SPEED_UNKNOWN		= 0xff,
 };
drivers/pci/hotplug/pciehp_ctrl.c +3 -3
diff -Nru a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -135,7 +135,7 @@
 	p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
 	p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
 
-	if (!getstatus) {
+	if (getstatus) {
 		/*
 		 * Switch opened
 		 */
@@ -1705,7 +1705,7 @@
 	}
 	
 	rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
-	if (rc || !getstatus) {
+	if (rc || getstatus) {
 		info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
 		up(&p_slot->ctrl->crit_sect);
 		return (0);
@@ -1792,7 +1792,7 @@
 	}
 
 	ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
-	if (ret || !getstatus) {
+	if (ret || getstatus) {
 		info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
 		up(&p_slot->ctrl->crit_sect);
 		return (0);
drivers/pci/hotplug/shpchp_ctrl.c +5 -5
diff -Nru a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -138,7 +138,7 @@
 	p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
 	p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
 
-	if (!getstatus) {
+	if (getstatus) {
 		/*
 		 * Switch opened
 		 */
@@ -1219,7 +1219,7 @@
 					up(&ctrl->crit_sect);
 				}
 			} else {
-				if ((bus_speed > 0x4) || (max_bus_speed > 0x4))  {
+				if (bus_speed > 0x4) {
 					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
 					return WRONG_BUS_FREQUENCY;
 				}
@@ -1302,7 +1302,7 @@
 					up(&ctrl->crit_sect);
 				}
 			} else {
-				if ((bus_speed > 0x2) || (max_bus_speed > 0x2))  {
+				if (bus_speed > 0x2) {
 					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
 					return WRONG_BUS_FREQUENCY;
 				}
@@ -2107,7 +2107,7 @@
 		return (0);
 	}
 	rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
-	if (rc || !getstatus) {
+	if (rc || getstatus) {
 		info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
 		up(&p_slot->ctrl->crit_sect);
 		return (0);
@@ -2192,7 +2192,7 @@
 		return (0);
 	}
 	ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
-	if (ret || !getstatus) {
+	if (ret || getstatus) {
 		info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
 		up(&p_slot->ctrl->crit_sect);
 		return (0);
drivers/pci/hotplug/shpchp_hpc.c +8 -7
diff -Nru a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
@@ -104,12 +104,12 @@
 #define PCIX_66MHZ_ECC		0x5
 #define PCIX_100MHZ_ECC		0x6
 #define PCIX_133MHZ_ECC		0x7
-#define PCIX_66MHZ_266		0x8
-#define PCIX_100MHZ_266		0x9
-#define PCIX_133MHZ_266		0x0a
-#define PCIX_66MHZ_533		0x0b
-#define PCIX_100MHZ_533		0x0c
-#define PCIX_133MHZ_533		0x0d
+#define PCIX_66MHZ_266		0x9
+#define PCIX_100MHZ_266		0xa
+#define PCIX_133MHZ_266		0xb
+#define PCIX_66MHZ_533		0x11
+#define PCIX_100MHZ_533		0x12
+#define PCIX_133MHZ_533		0x13
 
 /* Slot Configuration */
 #define SLOT_NUM		0x0000001F
@@ -464,7 +464,8 @@
 	slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
 	slot_status = (u16)slot_reg;
 
-	*status = ((slot_status & 0x0100) == 0) ? 1 : 0;
+	*status = ((slot_status & 0x0100) == 0) ? 0 : 1;   /* 0 -> close; 1 -> open */
+
 
 	DBG_LEAVE_ROUTINE 
 	return 0;
author
#12 lore raw

ChangeSet 1.1692.3.12, 2004/04/12 16:57:12-07:00, [email protected]

[PATCH] PCI Hotplug: php_phy_location.patch

Adds a file to show the pci hotplug slot location for the ppc64 driver only.

 drivers/pci/hotplug/rpadlpar_core.c |   23 +++-------
 drivers/pci/hotplug/rpaphp.h        |    2 
 drivers/pci/hotplug/rpaphp_core.c   |   23 +++-------
 drivers/pci/hotplug/rpaphp_slot.c   |   80 ++++++++++++++++++------------------
 4 files changed, 59 insertions(+), 69 deletions(-)
drivers/pci/hotplug/rpadlpar_core.c +8 -15
diff -Nru a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
@@ -79,25 +79,18 @@
 	return np;
 }
 
-static inline struct hotplug_slot *find_php_slot(char *drc_name)
-{
-	struct kobject *k;
-
-	k = kset_find_obj(&pci_hotplug_slots_subsys.kset, drc_name);
-	if (!k)
-		return NULL;
-
-	return to_hotplug_slot(k);
-}
-
 static struct slot *find_slot(char *drc_name)
 {
-	struct hotplug_slot *php_slot = find_php_slot(drc_name);
+	struct list_head *tmp, *n;
+	struct slot *slot;
 
-	if (!php_slot)
-		return NULL;
+        list_for_each_safe(tmp, n, &rpaphp_slot_head) {
+                slot = list_entry(tmp, struct slot, rpaphp_slot_list);
+                if (strcmp(slot->location, drc_name) == 0)
+                        return slot;
+        }
 
-	return (struct slot *) php_slot->private;
+        return NULL;
 }
 
 static void rpadlpar_claim_one_bus(struct pci_bus *b)
drivers/pci/hotplug/rpaphp.h +2 -0
diff -Nru a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
@@ -85,6 +85,7 @@
 	u32 type;
 	u32 power_domain;
 	char *name;
+	char *location;
 	struct device_node *dn;	/* slot's device_node in OFDT */
 	/* dn has phb info */
 	struct pci_dev *bridge;	/* slot's pci_dev in pci_devices */
@@ -129,5 +130,6 @@
 extern int register_slot(struct slot *slot);
 extern int rpaphp_get_power_status(struct slot *slot, u8 * value);
 extern int rpaphp_set_attention_status(struct slot *slot, u8 status);
+extern void rpaphp_sysfs_remove_attr_location(struct hotplug_slot *slot);
 	
 #endif				/* _PPC64PHP_H */
drivers/pci/hotplug/rpaphp_core.c +7 -16
diff -Nru a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
@@ -246,17 +246,14 @@
 int rpaphp_remove_slot(struct slot *slot)
 {
 	int retval = 0;
-	char *rm_link;
+	struct hotplug_slot *php_slot = slot->hotplug_slot;
 
-	dbg("%s - Entry: slot[%s]\n", __FUNCTION__, slot->name);
-	if (slot->dev_type == PCI_DEV)
-		rm_link = pci_name(slot->bridge);
-	else
-		rm_link = strstr(slot->dn->full_name, "@");
-
-	sysfs_remove_link(slot->hotplug_slot->kobj.parent, rm_link);
 	list_del(&slot->rpaphp_slot_list);
-	retval = pci_hp_deregister(slot->hotplug_slot);
+	
+	/* remove "php_location" file */
+	rpaphp_sysfs_remove_attr_location(php_slot);
+
+	retval = pci_hp_deregister(php_slot);
 	if (retval)
 		err("Problem unregistering a slot %s\n", slot->name);
 
@@ -380,14 +377,7 @@
 	 */
 
 	list_for_each_safe(tmp, n, &rpaphp_slot_head) {
-		char *rm_link;
-
 		slot = list_entry(tmp, struct slot, rpaphp_slot_list);
-		if (slot->dev_type == PCI_DEV)
-			rm_link = pci_name(slot->bridge);
-		else
-			rm_link = strstr(slot->dn->full_name, "@");
-		sysfs_remove_link(slot->hotplug_slot->kobj.parent, rm_link);
 		list_del(&slot->rpaphp_slot_list);
 		pci_hp_deregister(slot->hotplug_slot);
 	}
@@ -478,3 +468,4 @@
 
 EXPORT_SYMBOL_GPL(rpaphp_add_slot);
 EXPORT_SYMBOL_GPL(rpaphp_remove_slot);
+EXPORT_SYMBOL_GPL(rpaphp_slot_head);
drivers/pci/hotplug/rpaphp_slot.c +42 -38

108 lines not on this page · raw message