linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [BK PATCH] PCI fixes and PCI Express drivers for 2.6.11-rc1
@ 2005-01-17 22:01 Greg KH
  2005-01-17 22:01 ` [PATCH] PCI: add PCI Express Port Bus Driver subsystem Greg KH
  0 siblings, 1 reply; 14+ messages in thread
From: Greg KH @ 2005-01-17 22:01 UTC (permalink / raw)
  To: torvalds, akpm; +Cc: linux-kernel

Hi,

Here are some small PCI patches for 2.6.11-rc1, and the addition of a
new PCI Express subsystem (it's self contained, if you don't have PCI
Express, or select it, the code never gets built.)  All of these patches
have been in the past few -mm releases.

Please pull from:
	bk://kernel.bkbits.net/gregkh/linux/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.


 Documentation/PCIEBUS-HOWTO.txt   |  217 ++++++++++++++++++
 arch/i386/Kconfig                 |    4 
 arch/i386/pci/pcbios.c            |    4 
 drivers/Makefile                  |    2 
 drivers/pci/Makefile              |    2 
 drivers/pci/access.c              |    2 
 drivers/pci/hotplug/Kconfig       |   21 -
 drivers/pci/hotplug/pciehp.h      |    3 
 drivers/pci/hotplug/pciehp_core.c |   83 ++++--
 drivers/pci/hotplug/pciehp_hpc.c  |   21 -
 drivers/pci/msi.c                 |   39 +--
 drivers/pci/pci.c                 |    2 
 drivers/pci/pci.h                 |    2 
 drivers/pci/pcie/Kconfig          |   38 +++
 drivers/pci/pcie/Makefile         |    7 
 drivers/pci/pcie/portdrv.h        |   42 +++
 drivers/pci/pcie/portdrv_bus.c    |   88 +++++++
 drivers/pci/pcie/portdrv_core.c   |  453 ++++++++++++++++++++++++++++++++++++++
 drivers/pci/pcie/portdrv_pci.c    |  138 +++++++++++
 drivers/pci/probe.c               |   10 
 drivers/pci/remove.c              |   13 -
 drivers/pci/rom.c                 |   80 +++---
 drivers/pci/search.c              |    2 
 include/linux/pci_ids.h           |    4 
 include/linux/pcieport_if.h       |   74 ++++++
 25 files changed, 1209 insertions(+), 142 deletions(-)
-----


<jason.d.gaston:intel.com>:
  o PCI: pci_ids.h correction for Intel ICH7 - 2.6.10-bk13

Bjorn Helgaas:
  o PCI: use modern format for PCI addresses

David Howells:
  o PCI: Downgrade printk that complains about unsupported PCI PM caps

Greg Kroah-Hartman:
  o PCI: move pcie build into the drivers/pci/ subdirectory

Jesse Barnes:
  o PCI: rom.c cleanups

John Rose:
  o PCI: fix release_pcibus_dev() crash

Roland Dreier:
  o PCI: Clean up printks in msi.c

Thomas Gleixner:
  o PCI: Lock initializer cleanup - batch 4

Tom L. Nguyen:
  o PCI: add PCI Express Port Bus Driver subsystem


^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re:[PATCH] PCI: add PCI Express Port Bus Driver subsystem
@ 2005-01-18 19:28 long
  2005-01-18 18:36 ` [PATCH] " Greg KH
  0 siblings, 1 reply; 14+ messages in thread
From: long @ 2005-01-18 19:28 UTC (permalink / raw)
  To: greg; +Cc: linux-kernel, tom.l.nguyen

On Mon, 17 Jan 2005 15:49:08 -0800 Greg KH wrote:
> > +int pcie_port_device_register(struct pci_dev *dev)
> > +{
> > +	struct pcie_device *parent;
> > +	int status, type, capabilities, irq_mode, i;
> > +	int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
> > +	u16 reg16;
> > +
> > +	/* Get port type */
> > +	pci_read_config_word(dev, 
> > +		pci_find_capability(dev, PCI_CAP_ID_EXP) + 
> > +		PCIE_CAPABILITIES_REG, &reg16);
> > +	type = (reg16 >> 4) & PORT_TYPE_MASK;
> > +
> > +	/* Now get port services */
> > +	capabilities = get_port_device_capability(dev);
> > +	irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
> > +
> > +	/* Allocate parent */
> > +	parent = alloc_pcie_device(NULL, dev, type, 0, dev->irq, irq_mode);
> > +	if (!parent) 
> > +		return -ENOMEM;
> > +	
> > +	status = device_register(&parent->device);
> > +	if (status) {
> > +		kfree(parent);
> > +		return status;
> > +	}
>
>
> This puts all of the pcie "port" structures in /sys/devices/  Shouldn't
> you make the parent of the device you create point to the pci_dev
> structure that's passed into this function?  That would make the sysfs
> tree a lot saner I think.

The patch makes the parent of the device point to the pci_dev structure
that is passed into this function. If you think it is cleaner that the
patch should not, I will update the patch to reflect your input.

Thanks,
Long 

^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re:[PATCH] PCI: add PCI Express Port Bus Driver subsystem
@ 2005-01-19  1:59 long
  2005-01-19  1:03 ` [PATCH] " Greg KH
  0 siblings, 1 reply; 14+ messages in thread
From: long @ 2005-01-19  1:59 UTC (permalink / raw)
  To: greg; +Cc: linux-kernel, tom.l.nguyen

On Tue Jan 18 11:41:01 2005 Greg KH wrote:
>> >
>> >
>> > This puts all of the pcie "port" structures in /sys/devices/  Shouldn't
>> > you make the parent of the device you create point to the pci_dev
>> > structure that's passed into this function?  That would make the sysfs
>> > tree a lot saner I think.
>> 
>> The patch makes the parent of the device point to the pci_dev structure
>> that is passed into this function. If you think it is cleaner that the
>> patch should not, I will update the patch to reflect your input.
>
>That would be great, but it doesn't show up that way on my box.  All of
>the portX devices are in /sys/devices/ which is what I don't think you
>want.  I would love for them to have the parent of the pci_dev structure
>:)

Agree. Thanks for your inputs. The patch below include the changes based
on your previous post.

Signed-off-by: T. Long Nguyen <tom.l.nguyen@intel.com>

---------------------------------------------------------------------
diff -urpN greg-patch/drivers/pci/pcie/portdrv_bus.c greg-patch-update/drivers/pci/pcie/portdrv_bus.c
--- greg-patch/drivers/pci/pcie/portdrv_bus.c	2005-01-18 15:59:38.000000000 -0500
+++ greg-patch-update/drivers/pci/pcie/portdrv_bus.c	2005-01-18 16:03:47.000000000 -0500
@@ -14,8 +14,6 @@
 
 #include <linux/pcieport_if.h>
 
-static int generic_probe (struct device *dev) {	return 0;}
-static int generic_remove (struct device *dev) { return 0;}
 static int pcie_port_bus_match(struct device *dev, struct device_driver *drv);
 static int pcie_port_bus_suspend(struct device *dev, u32 state);
 static int pcie_port_bus_resume(struct device *dev);
@@ -27,23 +25,14 @@ struct bus_type pcie_port_bus_type = {
 	.resume		= pcie_port_bus_resume, 
 };
 
-struct device_driver pcieport_generic_driver = {
-	.name =	"pcieport",
-	.bus = &pcie_port_bus_type,
-	.probe = generic_probe,
-	.remove = generic_remove,
-};
-
 static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
 {
 	struct pcie_device *pciedev;
 	struct pcie_port_service_driver *driver;
 
-	if (	drv->bus != &pcie_port_bus_type || 
-		dev->bus != &pcie_port_bus_type	||
-		drv == &pcieport_generic_driver) {
+	if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
 		return 0;
-	}
+	
 	pciedev = to_pcie_device(dev);
 	driver = to_service_driver(drv);
 	if (   (driver->id_table->vendor != PCI_ANY_ID && 
diff -urpN greg-patch/drivers/pci/pcie/portdrv_core.c greg-patch-update/drivers/pci/pcie/portdrv_core.c
--- greg-patch/drivers/pci/pcie/portdrv_core.c	2005-01-18 15:59:38.000000000 -0500
+++ greg-patch-update/drivers/pci/pcie/portdrv_core.c	2005-01-18 16:06:51.000000000 -0500
@@ -17,8 +17,6 @@
 
 extern int pcie_mch_quirk;	/* MSI-quirk Indicator */
 
-extern struct device_driver pcieport_generic_driver;
-
 static int pcie_port_probe_service(struct device *dev)
 {
 	struct pcie_device *pciedev;
@@ -103,6 +101,7 @@ static int pcie_port_resume_service(stru
  */
 static void release_pcie_device(struct device *dev)
 {
+	printk(KERN_DEBUG "Free Port Service[%s]\n", dev->bus_id);
 	kfree(to_pcie_device(dev));			
 }
 
@@ -217,18 +216,18 @@ static int get_port_device_capability(st
 	return services;
 }
 
-static void pcie_device_init(struct pcie_device *parent, 
-			struct pcie_device *dev, 
-			int port_type, int service_type)
+static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, 
+	int port_type, int service_type, int irq, int irq_mode)
 {
 	struct device *device;
 
-	if (parent) {
-		dev->id.vendor = parent->port->vendor;
-		dev->id.device = parent->port->device;
-		dev->id.port_type = port_type;
-		dev->id.service_type = (1 << service_type);
-	}
+	dev->port = parent;
+	dev->interrupt_mode = irq_mode;
+	dev->irq = irq;
+	dev->id.vendor = parent->vendor;
+	dev->id.device = parent->device;
+	dev->id.port_type = port_type;
+	dev->id.service_type = (1 << service_type);
 
 	/* Initialize generic device interface */
 	device = &dev->device;
@@ -240,35 +239,23 @@ static void pcie_device_init(struct pcie
 	device->driver = NULL;
 	device->driver_data = NULL; 
 	device->release = release_pcie_device;	/* callback to free pcie dev */
-	sprintf(&device->bus_id[0], "%s.%02x", parent->device.bus_id, 
-			get_descriptor_id(port_type, service_type));
-	device->parent = ((parent == NULL) ? NULL : &parent->device);
+	sprintf(&device->bus_id[0], "pcie%02x", 
+		get_descriptor_id(port_type, service_type));
+	device->parent = &parent->dev;
 }
 
-static struct pcie_device* alloc_pcie_device(
-	struct pcie_device *parent, struct pci_dev *bridge, 
+static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, 
 	int port_type, int service_type, int irq, int irq_mode)
 {
 	struct pcie_device *device;
-	static int NR_PORTS = 0;
 
 	device = kmalloc(sizeof(struct pcie_device), GFP_KERNEL);
 	if (!device)
 		return NULL;
 
 	memset(device, 0, sizeof(struct pcie_device));
-	device->port = bridge;
-	device->interrupt_mode = irq_mode;
-	device->irq = irq;
-	if (!parent) {
-		pcie_device_init(NULL, device, port_type, service_type);
-		NR_PORTS++;
-		device->device.driver = &pcieport_generic_driver;
-		sprintf(&device->device.bus_id[0], "port%d", NR_PORTS); 
-	} else { 
-		pcie_device_init(parent, device, port_type, service_type);
-	}
-	printk(KERN_DEBUG "Allocate Port Device[%s]\n", device->device.bus_id);
+	pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
+	printk(KERN_DEBUG "Allocate Port Service[%s]\n", device->device.bus_id);
 	return device;
 }
 
@@ -291,7 +278,6 @@ int pcie_port_device_probe(struct pci_de
 
 int pcie_port_device_register(struct pci_dev *dev)
 {
-	struct pcie_device *parent;
 	int status, type, capabilities, irq_mode, i;
 	int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
 	u16 reg16;
@@ -306,27 +292,13 @@ int pcie_port_device_register(struct pci
 	capabilities = get_port_device_capability(dev);
 	irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
 
-	/* Allocate parent */
-	parent = alloc_pcie_device(NULL, dev, type, 0, dev->irq, irq_mode);
-	if (!parent) 
-		return -ENOMEM;
-	
-	status = device_register(&parent->device);
-	if (status) {
-		kfree(parent);
-		return status;
-	}
-	get_device(&parent->device);
-	pci_set_drvdata(dev, parent);	
-
 	/* Allocate child services if any */
 	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
 		struct pcie_device *child;
 
 		if (capabilities & (1 << i)) {
 			child = alloc_pcie_device(
-				parent,		/* parent */ 
-				dev, 		/* Root/Upstream/Downstream */
+				dev, 		/* parent */
 				type,		/* port type */ 
 				i,		/* service type */
 				vectors[i],	/* irq */
@@ -345,17 +317,21 @@ int pcie_port_device_register(struct pci
 }
 
 #ifdef CONFIG_PM
-int pcie_port_device_suspend(struct pcie_device *dev, u32 state)
+int pcie_port_device_suspend(struct pci_dev *dev, u32 state)
 {
-	struct list_head 		*head;
+	struct list_head 		*head, *tmp;
 	struct device 			*parent, *child;
 	struct device_driver 		*driver;
 	struct pcie_port_service_driver *service_driver;
 
-	parent = &dev->device;
+	parent = &dev->dev;
 	head = &parent->children;
-	while (!list_empty(head)) {
-		child = container_of(head->next, struct device, node);
+	tmp = head->next;
+	while (head != tmp) {
+		child = container_of(tmp, struct device, node);
+		tmp = tmp->next;
+		if (child->bus != &pcie_port_bus_type)
+			continue;
 		driver = child->driver;
 		if (!driver)
 			continue;
@@ -366,17 +342,21 @@ int pcie_port_device_suspend(struct pcie
 	return 0; 
 }
 
-int pcie_port_device_resume(struct pcie_device *dev) 
+int pcie_port_device_resume(struct pci_dev *dev) 
 { 
-	struct list_head 		*head;
+	struct list_head 		*head, *tmp;
 	struct device 			*parent, *child;
 	struct device_driver 		*driver;
 	struct pcie_port_service_driver *service_driver;
 
-	parent = &dev->device;
+	parent = &dev->dev;
 	head = &parent->children;
-	while (!list_empty(head)) {
-		child = container_of(head->next, struct device, node);
+	tmp = head->next;
+	while (head != tmp) {
+		child = container_of(tmp, struct device, node);
+		tmp = tmp->next;
+		if (child->bus != &pcie_port_bus_type)
+			continue;
 		driver = child->driver;
 		if (!driver)
 			continue;
@@ -389,45 +369,46 @@ int pcie_port_device_resume(struct pcie_
 }
 #endif
 
-void pcie_port_device_remove(struct pcie_device *dev)
+void pcie_port_device_remove(struct pci_dev *dev)
 {
-	struct list_head 		*head;
+	struct list_head 		*head, *tmp;
 	struct device 			*parent, *child;
 	struct device_driver 		*driver;
 	struct pcie_port_service_driver *service_driver;
+	int interrupt_mode = PCIE_PORT_INTx_MODE;
 
-	parent = &dev->device;
+	parent = &dev->dev;
 	head = &parent->children;
-	while (!list_empty(head)) {
-		child = container_of(head->next, struct device, node);
+	tmp = head->next;
+	while (head != tmp) {
+		child = container_of(tmp, struct device, node);
+		tmp = tmp->next;
+		if (child->bus != &pcie_port_bus_type)
+			continue;
 		driver = child->driver;
 		if (driver) { 
 			service_driver = to_service_driver(driver);
 			if (service_driver->remove)  
 				service_driver->remove(to_pcie_device(child));
 		}
+		interrupt_mode = (to_pcie_device(child))->interrupt_mode;
 		put_device(child);
 		device_unregister(child);
 	}
-
 	/* Switch to INTx by default if MSI enabled */
-	if (dev->interrupt_mode == PCIE_PORT_MSIX_MODE)
-		pci_disable_msix(dev->port);
-	else if (dev->interrupt_mode == PCIE_PORT_MSI_MODE)
-		pci_disable_msi(dev->port);
-	put_device(parent);
-	device_unregister(parent);
+	if (interrupt_mode == PCIE_PORT_MSIX_MODE)
+		pci_disable_msix(dev);
+	else if (interrupt_mode == PCIE_PORT_MSI_MODE)
+		pci_disable_msi(dev);
 }
 
 void pcie_port_bus_register(void)
 {
 	bus_register(&pcie_port_bus_type);
-	driver_register(&pcieport_generic_driver);
 }
 
 void pcie_port_bus_unregister(void)
 {
-	driver_unregister(&pcieport_generic_driver);
 	bus_unregister(&pcie_port_bus_type);
 }
 
diff -urpN greg-patch/drivers/pci/pcie/portdrv.h greg-patch-update/drivers/pci/pcie/portdrv.h
--- greg-patch/drivers/pci/pcie/portdrv.h	2005-01-18 15:59:38.000000000 -0500
+++ greg-patch-update/drivers/pci/pcie/portdrv.h	2005-01-18 16:08:33.000000000 -0500
@@ -28,14 +28,13 @@
 #define get_descriptor_id(type, service) (((type - 4) << 4) | service)
 
 extern struct bus_type pcie_port_bus_type;
-extern struct device_driver pcieport_generic_driver;
 extern int pcie_port_device_probe(struct pci_dev *dev);
 extern int pcie_port_device_register(struct pci_dev *dev);
 #ifdef CONFIG_PM
-extern int pcie_port_device_suspend(struct pcie_device *dev, u32 state);
-extern int pcie_port_device_resume(struct pcie_device *dev);
+extern int pcie_port_device_suspend(struct pci_dev *dev, u32 state);
+extern int pcie_port_device_resume(struct pci_dev *dev);
 #endif
-extern void pcie_port_device_remove(struct pcie_device *dev);
+extern void pcie_port_device_remove(struct pci_dev *dev);
 extern void pcie_port_bus_register(void);
 extern void pcie_port_bus_unregister(void);
 
diff -urpN greg-patch/drivers/pci/pcie/portdrv_pci.c greg-patch-update/drivers/pci/pcie/portdrv_pci.c
--- greg-patch/drivers/pci/pcie/portdrv_pci.c	2005-01-18 15:59:38.000000000 -0500
+++ greg-patch-update/drivers/pci/pcie/portdrv_pci.c	2005-01-18 16:39:07.000000000 -0500
@@ -63,34 +63,18 @@ static int __devinit pcie_portdrv_probe 
 
 static void pcie_portdrv_remove (struct pci_dev *dev)
 {
-	struct pcie_device *pciedev;
-
-      	pciedev = (struct pcie_device *)pci_get_drvdata(dev);
-	if (pciedev) {
-		pcie_port_device_remove(pciedev);
-		pci_set_drvdata(dev, NULL); 
-	}
+	pcie_port_device_remove(dev);
 }
 
 #ifdef CONFIG_PM
 static int pcie_portdrv_suspend (struct pci_dev *dev, u32 state)
 {
-	struct pcie_device *pciedev;
-	
-      	pciedev = (struct pcie_device *)pci_get_drvdata(dev);
-	if (pciedev) 
-		pcie_port_device_suspend(pciedev, state);
-	return 0;
+	return pcie_port_device_suspend(dev, state);
 }
 
 static int pcie_portdrv_resume (struct pci_dev *dev)
 {
-	struct pcie_device *pciedev;
-	
-      	pciedev = (struct pcie_device *)pci_get_drvdata(dev);
-	if (pciedev) 
-		pcie_port_device_resume(pciedev);
-	return 0;
+	return pcie_port_device_resume(dev);
 }
 #endif
 

^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re:[PATCH] PCI: add PCI Express Port Bus Driver subsystem
@ 2005-01-24 20:10 long
  2005-02-01  7:39 ` [PATCH] " Greg KH
  0 siblings, 1 reply; 14+ messages in thread
From: long @ 2005-01-24 20:10 UTC (permalink / raw)
  To: greg; +Cc: linux-kernel, tom.l.nguyen

On Tuesday, January 18, 2005 5:03 PM Greg KH wrote:
>> >
>> >That would be great, but it doesn't show up that way on my box.  All
>> >of
>> >the portX devices are in /sys/devices/ which is what I don't think
>> >you
>> >want.  I would love for them to have the parent of the pci_dev
>> >structure
>> >:)
>> 
>> Agree. Thanks for your inputs. The patch below include the changes
>> based on your previous post.
>
>Hm, that seems like a pretty big patch just to add a pointer to a parent
>device :)
>
>What really does this patch do?  What does the sysfs tree now look like?

Before changes:

The patch makes the parent of the device pointing to the pci_dev
structure. The parents portX devices are in /sys/devices which
should be removed based on your suggestions. Below is /sys/devices
before any changes made.

/sys/devices
	|
	__ ide0 
	|
	__ pci0000:00
	|
	__ pnp0
	|
	__ port1
	|	|
	|  	__ port1.00
	|	|
	|	__ port1.01
	|	.
	|	.
	|	.
	|
	__ port2
	|
 	__ port3
	|
	__ system

After changes:

The parents portX devices are no longer necessary because port1.00
and port1.01 devices shoud have the parent of the pci_dev structure
(based on your suggestion). The patch does the following changes:

- remove code creating and handling the parent portX devices.
- rename portX.YZ to pcieYZ (for example port1.00 renamed to pcie00)
  since portX is no longer needed.
- make pcieYZ have the parent of the pci_dev structure.

Below is /sys/devices after changes made to the patch.

/sys/devices
	|
	__ ide0 
	|
	__ pci0000:00
	|	|
	|	__ 0000:00:00.0
	|	|
	|	__ 0000:00:04.0
	|	|	|
	|	.	__ class
	|	.	|
	|	.	__ pcie00
	|		|
	|		__ pcie01
	|		.
	|		.	
	|		.
	|
	__ platform
	|
	__ pnp0
	|
	__ system


Please let me know what you think of the changes.

Thanks,
Long

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2005-02-01  7:43 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-17 22:01 [BK PATCH] PCI fixes and PCI Express drivers for 2.6.11-rc1 Greg KH
2005-01-17 22:01 ` [PATCH] PCI: add PCI Express Port Bus Driver subsystem Greg KH
2005-01-17 22:01   ` [PATCH] PCI: use modern format for PCI addresses Greg KH
2005-01-17 22:01     ` [PATCH] PCI: pci_ids.h correction for Intel ICH7 - 2.6.10-bk13 Greg KH
2005-01-17 22:01       ` [PATCH] PCI: Clean up printks in msi.c Greg KH
2005-01-17 22:01         ` [PATCH] PCI: rom.c cleanups Greg KH
2005-01-17 22:01           ` [PATCH] PCI: Downgrade printk that complains about unsupported PCI PM caps Greg KH
2005-01-17 22:01             ` [PATCH] PCI: Lock initializer cleanup - batch 4 Greg KH
2005-01-17 22:01               ` [PATCH] PCI: fix release_pcibus_dev() crash Greg KH
2005-01-17 22:01                 ` PCI: move pcie build into the drivers/pci/ subdirectory Greg KH
2005-01-17 23:49   ` [PATCH] PCI: add PCI Express Port Bus Driver subsystem Greg KH
2005-01-18 19:28 long
2005-01-18 18:36 ` [PATCH] " Greg KH
2005-01-19  1:59 long
2005-01-19  1:03 ` [PATCH] " Greg KH
2005-01-24 20:10 long
2005-02-01  7:39 ` [PATCH] " Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).