2003-05-29 20:04:27

by Mark Haverkamp

[permalink] [raw]
Subject: [PATCH] pci bridge class code

This adds pci-pci bridge driver model class code. Entries appear in
/sys/class/pci_bridge.



Makefile | 2
pci-bridge.c | 205 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 206 insertions(+), 1 deletion(-)

===== drivers/pci/Makefile 1.28 vs edited =====
--- 1.28/drivers/pci/Makefile Mon May 5 10:58:50 2003
+++ edited/drivers/pci/Makefile Thu May 29 10:32:28 2003
@@ -4,7 +4,7 @@

obj-y += access.o bus.o probe.o pci.o pool.o quirks.o \
names.o pci-driver.o search.o hotplug.o \
- pci-sysfs.o
+ pci-sysfs.o pci-bridge.o
obj-$(CONFIG_PM) += power.o
obj-$(CONFIG_PROC_FS) += proc.o

===== drivers/pci/pci-bridge.c 1.1 vs edited =====
--- 1.1/drivers/pci/pci-bridge.c Thu May 29 11:00:38 2003
+++ edited/drivers/pci/pci-bridge.c Thu May 29 12:57:13 2003
@@ -0,0 +1,205 @@
+/*
+ * drivers/pci/pci-bridge.c
+ *
+ * Copyright (c) 2003 Mark Haverkamp <[email protected]>
+ *
+ * pci bridge driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+static int __devinit pci_bridge_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id);
+static void __devexit pci_bridge_remove(struct pci_dev *pci);
+
+static void pci_bridge_create_sysfs_files(struct device *device);
+
+static struct class pci_bridge_class = {
+ .name = "pci_bridge",
+};
+
+static struct class_device class_dev_data;
+
+
+static struct pci_device_id pci_bridge_id[] __devinitdata = {
+ {
+ .vendor = PCI_ANY_ID,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class = PCI_CLASS_BRIDGE_PCI << 8,
+ .class_mask = 0xffff00,
+ .driver_data = 0,
+ },
+ {0},
+};
+
+static struct pci_driver driver = {
+ .name = "pci_bridge",
+ .id_table = pci_bridge_id,
+ .probe = pci_bridge_probe,
+ .remove = __devexit_p(pci_bridge_remove),
+};
+
+struct pci_bridge_dev_data {
+ u32 br_num;
+ u8 primary_bus;
+ u8 secondary_bus;
+ u8 subordinate_bus;
+};
+
+static u32 pci_bridge_num = 0;
+static spinlock_t br_config_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * pci_bridge_probe - Initialze driver for pci-pci bridge.
+ *
+ * @pci: Pointer to pci bridge device data.
+ * @pci_id: Pointer to pci_bridge_id data.
+ */
+static int __devinit pci_bridge_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ int err = 0;
+ u32 buses;
+ struct pci_bridge_dev_data *dev;
+
+
+ dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
+ if (dev == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ spin_lock(&br_config_lock);
+ dev->br_num = pci_bridge_num++;
+ spin_unlock(&br_config_lock);
+
+ pci_read_config_dword(pci, PCI_PRIMARY_BUS, &buses);
+ dev->primary_bus = buses & 0xff;
+ dev->secondary_bus = (buses >> 8) & 0xff;
+ dev->subordinate_bus = (buses >> 16) & 0xff;
+
+ pci_set_drvdata(pci, dev);
+
+ memset(&class_dev_data, 0, sizeof(class_dev_data));
+ class_dev_data.dev = &pci->dev;
+ class_dev_data.class = &pci_bridge_class;
+ sprintf(class_dev_data.class_id, "pci_bridge%d", dev->br_num);
+
+ pci_bridge_create_sysfs_files(&pci->dev);
+
+ err = class_device_register(&class_dev_data);
+
+out:
+ return err;
+
+}
+
+/*
+ * pci_bridge_remove - Clean up on device removal
+ *
+ * @pci: Pointer to pci bridge device data.
+ */
+static void __devexit pci_bridge_remove(struct pci_dev *pci)
+{
+ class_device_unregister(&class_dev_data);
+}
+
+/*
+ * pci_bridge_init - initialize module.
+ */
+static int __init pci_bridge_init(void)
+{
+
+ int err;
+
+ err = class_register(&pci_bridge_class);
+ if (err < 0 ) {
+ return err;
+ }
+
+ err = pci_module_init(&driver);
+ if (err < 0) {
+ class_unregister(&pci_bridge_class);
+ }
+
+ return err;
+
+}
+
+/*
+ * pci_bridge_exit - Cleanup on module removal
+ */
+static void __exit pci_bridge_exit(void)
+{
+ pci_unregister_driver(&driver);
+ class_unregister(&pci_bridge_class);
+}
+
+/*
+ * Display pci-pci bridge attributes.
+ */
+
+static ssize_t pci_bridge_show_primary(struct device *device, char *buf)
+{
+ struct pci_bridge_dev_data *dev = dev_get_drvdata(device);
+
+ if (dev == NULL) {
+ return 0;
+ }
+
+ return sprintf(buf, "%u\n", dev->primary_bus);
+}
+static DEVICE_ATTR(primary_bus, S_IRUGO, pci_bridge_show_primary, NULL);
+
+static ssize_t pci_bridge_show_secondary(struct device *device, char *buf)
+{
+ struct pci_bridge_dev_data *dev = dev_get_drvdata(device);
+
+ if (dev == NULL) {
+ return 0;
+ }
+
+ return sprintf(buf, "%u\n", dev->secondary_bus);
+}
+static DEVICE_ATTR(secondary_bus, S_IRUGO, pci_bridge_show_secondary, NULL);
+
+static ssize_t pci_bridge_show_subordinate(struct device *device, char *buf)
+{
+ struct pci_bridge_dev_data *dev = dev_get_drvdata(device);
+
+ if (dev == NULL) {
+ return 0;
+ }
+
+ return sprintf(buf, "%u\n", dev->subordinate_bus);
+}
+static DEVICE_ATTR(subordinate_bus, S_IRUGO, pci_bridge_show_subordinate, NULL);
+
+
+/*
+ * pci_bridge_create_sysfs_files - create sysfs files for pci-pci bridge.
+ *
+ * @device: Pointer to device data for the pci-pci bridge.
+ */
+static void pci_bridge_create_sysfs_files(struct device *device)
+{
+ device_create_file(device, &dev_attr_primary_bus);
+ device_create_file(device, &dev_attr_secondary_bus);
+ device_create_file(device, &dev_attr_subordinate_bus);
+}
+
+MODULE_DEVICE_TABLE(pci, pci_bridge_id);
+module_init(pci_bridge_init);
+module_exit(pci_bridge_exit);
+MODULE_AUTHOR("Mark Haverkamp");
+MODULE_DESCRIPTION("PCI bridge driver");
+MODULE_LICENSE("GPL");



--
Mark Haverkamp <[email protected]>


2003-05-29 20:27:29

by Russell King

[permalink] [raw]
Subject: Re: [PATCH] pci bridge class code

On Thu, May 29, 2003 at 01:17:42PM -0700, Mark Haverkamp wrote:
> This adds pci-pci bridge driver model class code. Entries appear in
> /sys/class/pci_bridge.

Hmm. Ok.

How do you propose to handle the following case:

Mobility Electronics supply a Cardbus to PCI bridged "docking station"
which has a PCI-PCI bridge on with vendor stuff above 0x40. It appears
as a standard PCI-PCI bridge; the only specific identifying information
are the device and vendor IDs. How can I guarantee that a driver I
write for this device will be picked up in preference to your driver.

(Given that your driver would probably be always loaded, and my driver
could well be a loadable module.)

I'm not saying that I will need to do this, but this is something which
needs to be carefully thought about if we're going to provide a generic
driver.

--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html

2003-05-30 10:29:00

by Alan

[permalink] [raw]
Subject: Re: [PATCH] pci bridge class code

On Iau, 2003-05-29 at 21:40, Russell King wrote:
> On Thu, May 29, 2003 at 01:17:42PM -0700, Mark Haverkamp wrote:
> > This adds pci-pci bridge driver model class code. Entries appear in
> > /sys/class/pci_bridge.
>
> Hmm. Ok.
>
> How do you propose to handle the following case:
>
> Mobility Electronics supply a Cardbus to PCI bridged "docking station"
> which has a PCI-PCI bridge on with vendor stuff above 0x40. It appears
> as a standard PCI-PCI bridge; the only specific identifying information
> are the device and vendor IDs. How can I guarantee that a driver I
> write for this device will be picked up in preference to your driver.
>
> (Given that your driver would probably be always loaded, and my driver
> could well be a loadable module.)

The same is true of serveral hot docking bridges such as the one on the
IBM TP600 and also of other devices which happen to be both a PCI-PCI
bridge and have other magic stuck on them.


2003-05-30 22:58:31

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] pci bridge class code

On Thu, May 29, 2003 at 01:17:42PM -0700, Mark Haverkamp wrote:
> This adds pci-pci bridge driver model class code. Entries appear in
> /sys/class/pci_bridge.

Nice, but I don't see the need for the extra class information, as it
doesn't really give us anything new, right? So without the class stuff
might be nice.

> +MODULE_AUTHOR("Mark Haverkamp");
> +MODULE_DESCRIPTION("PCI bridge driver");
> +MODULE_LICENSE("GPL");

This isn't needed, as you can't build your code as a module with your
patch.

thanks,

greg k-h

2003-06-02 11:43:03

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH] pci bridge class code

On Fri, 2003-05-30 at 11:44, Alan Cox wrote:

> The same is true of serveral hot docking bridges such as the one on the
> IBM TP600 and also of other devices which happen to be both a PCI-PCI
> bridge and have other magic stuck on them.

Maybe we could find some way to prioritize matching ? It's a bit late now,
but well... if the match functions returned an integer, 0 beeing lower match,
we could have some kind of prioritization.

That way, a class match would have lower priority than a vendorID/deviceID
match, etc...

Ben.

2003-06-02 12:19:39

by Russell King

[permalink] [raw]
Subject: Re: [PATCH] pci bridge class code

On Mon, Jun 02, 2003 at 01:56:04PM +0200, Benjamin Herrenschmidt wrote:
> On Fri, 2003-05-30 at 11:44, Alan Cox wrote:
>
> > The same is true of serveral hot docking bridges such as the one on the
> > IBM TP600 and also of other devices which happen to be both a PCI-PCI
> > bridge and have other magic stuck on them.
>
> Maybe we could find some way to prioritize matching ? It's a bit late now,
> but well... if the match functions returned an integer, 0 beeing lower match,
> we could have some kind of prioritization.
>
> That way, a class match would have lower priority than a vendorID/deviceID
> match, etc...

That would not help the case when you have the "generic" bridge module
loaded and the specific bridge driver as a loadable module.

--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html

2003-06-02 12:26:08

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH] pci bridge class code

On Mon, 2003-06-02 at 14:32, Russell King wrote:

> That would not help the case when you have the "generic" bridge module
> loaded and the specific bridge driver as a loadable module.

Well... we could store the match score of the driver, and if a newer
driver comes with a better match, call a replace() callback in the
current owner to ask if it allows "live" replacement... But that's
far beyond my original idea though

Ben.

2003-06-02 14:11:53

by Mark Haverkamp

[permalink] [raw]
Subject: Re: [PATCH] pci bridge class code

On Mon, 2003-06-02 at 05:39, Benjamin Herrenschmidt wrote:
> On Mon, 2003-06-02 at 14:32, Russell King wrote:
>
> > That would not help the case when you have the "generic" bridge module
> > loaded and the specific bridge driver as a loadable module.
>
> Well... we could store the match score of the driver, and if a newer
> driver comes with a better match, call a replace() callback in the
> current owner to ask if it allows "live" replacement... But that's
> far beyond my original idea though

That is something I was considering also. I'm not sure how big of a
change it would be yet. I started looking at it a little bit on Friday.

Mark.

--
Mark Haverkamp <[email protected]>

2003-06-02 20:16:29

by Mark Haverkamp

[permalink] [raw]
Subject: Re: [PATCH] pci bridge class code

On Fri, 2003-05-30 at 16:13, Greg KH wrote:
> On Thu, May 29, 2003 at 01:17:42PM -0700, Mark Haverkamp wrote:
> > This adds pci-pci bridge driver model class code. Entries appear in
> > /sys/class/pci_bridge.
>
> Nice, but I don't see the need for the extra class information, as it
> doesn't really give us anything new, right? So without the class stuff
> might be nice.
>

I'm not sure I understand what you are saying here. Could you clarify?

Thanks,
Mark.

> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
Mark Haverkamp <[email protected]>

2003-06-02 20:20:30

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] pci bridge class code

On Mon, Jun 02, 2003 at 01:30:56PM -0700, Mark Haverkamp wrote:
> On Fri, 2003-05-30 at 16:13, Greg KH wrote:
> > On Thu, May 29, 2003 at 01:17:42PM -0700, Mark Haverkamp wrote:
> > > This adds pci-pci bridge driver model class code. Entries appear in
> > > /sys/class/pci_bridge.
> >
> > Nice, but I don't see the need for the extra class information, as it
> > doesn't really give us anything new, right? So without the class stuff
> > might be nice.
> >
>
> I'm not sure I understand what you are saying here. Could you clarify?

The /sys/class/pci_bridge entries are redundant, as they don't show any
new info that isn't already in /sys/bus/pci/drivers/pci_bridge, right?
I don't think that class directory or the class_device stuff is
necessary.

thanks,

greg k-h