linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* RE: Is there a user space pci rescan method?
@ 2004-09-22 22:00 Dave Aubin
  2004-09-22 23:58 ` Jan Dittmer
  0 siblings, 1 reply; 31+ messages in thread
From: Dave Aubin @ 2004-09-22 22:00 UTC (permalink / raw)
  To: Alan Cox; +Cc: Linux Kernel Mailing List

Hi,

  I know very little about hotplug, but does make sense.
How do you motivate a hotplug insertion event?  Or should
I just go read the /docs on hotplugging?  Any help is
Appreciated:)

Thanks,
Dave:) 

-----Original Message-----
From: Alan Cox [mailto:alan@lxorguk.ukuu.org.uk] 
Sent: Wednesday, September 22, 2004 4:05 PM
To: Dave Aubin
Cc: Linux Kernel Mailing List
Subject: Re: Is there a user space pci rescan method?

On Mer, 2004-09-22 at 21:30, Dave Aubin wrote:
> Hi,
>  
>   Is there a user space or perhaps simple kernel module way to rescan 
> the pci bus?  I currently have a user mode program modify the pci bus,

> but I can not push the user mode program to the bios for reasons I 
> can't get in to.

Take a look at drivers/hotplug. As far as Linux is concerned you've got
a hotplug PCI slot if you have to poke at it. Alternatively if its a
general funny such as a card you have to poke to reveal devices behind
it a PCI quirk would probably do the trick.


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

* Re: Is there a user space pci rescan method?
  2004-09-22 22:00 Is there a user space pci rescan method? Dave Aubin
@ 2004-09-22 23:58 ` Jan Dittmer
  2004-09-23  0:26   ` Greg KH
  0 siblings, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-09-22 23:58 UTC (permalink / raw)
  To: Dave Aubin; +Cc: Alan Cox, Linux Kernel Mailing List

Dave Aubin wrote:
> Hi,
> 
>   I know very little about hotplug, but does make sense.
> How do you motivate a hotplug insertion event?  Or should
> I just go read the /docs on hotplugging?  Any help is
> Appreciated:)

There is a "fake" hotplug driver which works for normal pci. But last
time I looked at it, it did only support hot disabling, not hot enabling
- but this surely can be fixed.

Thanks,

Jan

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

* Re: Is there a user space pci rescan method?
  2004-09-22 23:58 ` Jan Dittmer
@ 2004-09-23  0:26   ` Greg KH
  2004-09-23 15:04     ` Jan Dittmer
  0 siblings, 1 reply; 31+ messages in thread
From: Greg KH @ 2004-09-23  0:26 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: Dave Aubin, Alan Cox, Linux Kernel Mailing List

On Thu, Sep 23, 2004 at 01:58:32AM +0200, Jan Dittmer wrote:
> Dave Aubin wrote:
> > Hi,
> > 
> >   I know very little about hotplug, but does make sense.
> > How do you motivate a hotplug insertion event?  Or should
> > I just go read the /docs on hotplugging?  Any help is
> > Appreciated:)
> 
> There is a "fake" hotplug driver which works for normal pci. But last
> time I looked at it, it did only support hot disabling, not hot enabling
> - but this surely can be fixed.

Yes, hot "enabling" has been left for someone to add to the driver, if
you read the comments in it :)

Good luck,

greg k-h

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

* Re: Is there a user space pci rescan method?
  2004-09-23  0:26   ` Greg KH
@ 2004-09-23 15:04     ` Jan Dittmer
  2004-09-23 16:49       ` Rolf Eike Beer
  2004-09-23 23:31       ` Greg KH
  0 siblings, 2 replies; 31+ messages in thread
From: Jan Dittmer @ 2004-09-23 15:04 UTC (permalink / raw)
  To: Greg KH; +Cc: Linux Kernel Mailing List

Greg KH wrote:
> On Thu, Sep 23, 2004 at 01:58:32AM +0200, Jan Dittmer wrote:
> 
>>Dave Aubin wrote:
>>
>>>Hi,
>>>
>>>  I know very little about hotplug, but does make sense.
>>>How do you motivate a hotplug insertion event?  Or should
>>>I just go read the /docs on hotplugging?  Any help is
>>>Appreciated:)
>>
>>There is a "fake" hotplug driver which works for normal pci. But last
>>time I looked at it, it did only support hot disabling, not hot enabling
>>- but this surely can be fixed.
> 
> 
> Yes, hot "enabling" has been left for someone to add to the driver, if
> you read the comments in it :)
> 

I read them and started playing around with this driver. So echoing 0 in
 /sys/bus/pci/slots/*/power disables the pci device. The problem I see
is, that the tree with the device is disappearing. So how am I supposed
to re-enable the device. I've no real hotplug hardware to play with, so
I'm bound to reading the source code in drivers/pci/hotplug and testing
with fakephp. I found your utility pcihpview (v0.5) which searches for
/sys/bus/pci/hotplug_slots. But grepping the kernel tree doesn't show
any mentioning of it - so I suppose it is outdated.
Is there anywhere a current article (or Documentation/pci_hotplug.txt)
about the state of PCI hotplug and how this is supposed to work?

Thanks,

Jan

ps: Meanwhile I found dummyphp on the pcihpd mailinglist. This doesn't
remove the device from /sys/bus/pci/slots/*/power . Still I'd like
to know the offical way.

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

* Re: Is there a user space pci rescan method?
  2004-09-23 15:04     ` Jan Dittmer
@ 2004-09-23 16:49       ` Rolf Eike Beer
  2004-09-23 16:53         ` Jan Dittmer
  2004-09-23 23:31       ` Greg KH
  1 sibling, 1 reply; 31+ messages in thread
From: Rolf Eike Beer @ 2004-09-23 16:49 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: linux-kernel

Jan Dittmer wrote:
> Greg KH wrote:
> > On Thu, Sep 23, 2004 at 01:58:32AM +0200, Jan Dittmer wrote:
> >>Dave Aubin wrote:
> >>>Hi,
> >>>
> >>>  I know very little about hotplug, but does make sense.
> >>>How do you motivate a hotplug insertion event?  Or should
> >>>I just go read the /docs on hotplugging?  Any help is
> >>>Appreciated:)
> >>
> >>There is a "fake" hotplug driver which works for normal pci. But last
> >>time I looked at it, it did only support hot disabling, not hot enabling
> >>- but this surely can be fixed.
> >
> > Yes, hot "enabling" has been left for someone to add to the driver, if
> > you read the comments in it :)

Hot enabling works for month in dummyphp...

> I read them and started playing around with this driver. So echoing 0 in
>  /sys/bus/pci/slots/*/power disables the pci device. The problem I see
> is, that the tree with the device is disappearing. So how am I supposed
> to re-enable the device. I've no real hotplug hardware to play with, so
> I'm bound to reading the source code in drivers/pci/hotplug and testing
> with fakephp. I found your utility pcihpview (v0.5) which searches for
> /sys/bus/pci/hotplug_slots. But grepping the kernel tree doesn't show
> any mentioning of it - so I suppose it is outdated.
> Is there anywhere a current article (or Documentation/pci_hotplug.txt)
> about the state of PCI hotplug and how this is supposed to work?

Just search the archive of pcihpd-discuss@lists.sourceforge.net for dummyphp, 
this is the version that works. I'll rediff it soon and hope Greg will accept 
it this time.

Message-Id to search for: <200403120947.13046@bilbo.math.uni-mannheim.de>

Eike

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

* Re: Is there a user space pci rescan method?
  2004-09-23 16:49       ` Rolf Eike Beer
@ 2004-09-23 16:53         ` Jan Dittmer
  2004-09-23 17:05           ` Rolf Eike Beer
  0 siblings, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-09-23 16:53 UTC (permalink / raw)
  To: Rolf Eike Beer; +Cc: linux-kernel

Rolf Eike Beer wrote:
> Just search the archive of pcihpd-discuss@lists.sourceforge.net for dummyphp, 
> this is the version that works. I'll rediff it soon and hope Greg will accept 
> it this time.
> 
> Message-Id to search for: <200403120947.13046@bilbo.math.uni-mannheim.de>

You didn't read my p.s. ... I found it and it's working quite nice. Already
discovered a bug in dv1394. Just one thing: Can you strip DUMMY- from the
name in /sys/bus/pci/slots/ ? It's really ugly and you can't mix different
hotplug drivers anyway.

Thanks,

Jan

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

* Re: Is there a user space pci rescan method?
  2004-09-23 16:53         ` Jan Dittmer
@ 2004-09-23 17:05           ` Rolf Eike Beer
  2004-09-24 10:41             ` Rolf Eike Beer
  0 siblings, 1 reply; 31+ messages in thread
From: Rolf Eike Beer @ 2004-09-23 17:05 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: linux-kernel

Jan Dittmer wrote:
> Rolf Eike Beer wrote:
> > Just search the archive of pcihpd-discuss@lists.sourceforge.net for
> > dummyphp, this is the version that works. I'll rediff it soon and hope
> > Greg will accept it this time.
> >
> > Message-Id to search for: <200403120947.13046@bilbo.math.uni-mannheim.de>
>
> You didn't read my p.s. ... I found it and it's working quite nice. Already

Ehm, yes. Sorry, around 1900 local time and no real breakfast until now.

> discovered a bug in dv1394. Just one thing: Can you strip DUMMY- from the
> name in /sys/bus/pci/slots/ ? It's really ugly and you can't mix different
> hotplug drivers anyway.

Sounds reasonable.

Eike

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

* Re: Is there a user space pci rescan method?
  2004-09-23 15:04     ` Jan Dittmer
  2004-09-23 16:49       ` Rolf Eike Beer
@ 2004-09-23 23:31       ` Greg KH
  1 sibling, 0 replies; 31+ messages in thread
From: Greg KH @ 2004-09-23 23:31 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: Linux Kernel Mailing List

On Thu, Sep 23, 2004 at 05:04:38PM +0200, Jan Dittmer wrote:
> Greg KH wrote:
> > On Thu, Sep 23, 2004 at 01:58:32AM +0200, Jan Dittmer wrote:
> > 
> >>Dave Aubin wrote:
> >>
> >>>Hi,
> >>>
> >>>  I know very little about hotplug, but does make sense.
> >>>How do you motivate a hotplug insertion event?  Or should
> >>>I just go read the /docs on hotplugging?  Any help is
> >>>Appreciated:)
> >>
> >>There is a "fake" hotplug driver which works for normal pci. But last
> >>time I looked at it, it did only support hot disabling, not hot enabling
> >>- but this surely can be fixed.
> > 
> > 
> > Yes, hot "enabling" has been left for someone to add to the driver, if
> > you read the comments in it :)
> > 
> 
> I read them and started playing around with this driver. So echoing 0 in
>  /sys/bus/pci/slots/*/power disables the pci device. The problem I see
> is, that the tree with the device is disappearing. So how am I supposed
> to re-enable the device.

You need to add another sysfs file called "rescan" or something.
Writing to that file will cause the kernel to rescan pci space, and add
any devices it finds that are not already present.  The code to do that
can be taken from the pci startup code in the kernel today.

> I've no real hotplug hardware to play with, so I'm bound to reading
> the source code in drivers/pci/hotplug and testing with fakephp.

That's fine.  You don't need real hotplug pci hardware to use fakephp,
that's what the driver is for :)

> I found your utility pcihpview (v0.5) which searches for
> /sys/bus/pci/hotplug_slots. But grepping the kernel tree doesn't show
> any mentioning of it - so I suppose it is outdated.

That's a 2.4 interface.  I need to get a new version of that program out
there that works for 2.6 one of these days (the bk version of the
program has this support already in it, if you want to mess with
that...)

> Is there anywhere a current article (or Documentation/pci_hotplug.txt)
> about the state of PCI hotplug and how this is supposed to work?

Not really, sorry.

> ps: Meanwhile I found dummyphp on the pcihpd mailinglist. This doesn't
> remove the device from /sys/bus/pci/slots/*/power . Still I'd like
> to know the offical way.

That's the driver that I based fakephp on.  It's a good starting point
for what it sounds like you want to do.

Hope this helps,

greg k-h

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

* Re: Is there a user space pci rescan method?
  2004-09-23 17:05           ` Rolf Eike Beer
@ 2004-09-24 10:41             ` Rolf Eike Beer
  2004-09-24 11:42               ` Jan Dittmer
  2004-09-24 12:40               ` Jan Dittmer
  0 siblings, 2 replies; 31+ messages in thread
From: Rolf Eike Beer @ 2004-09-24 10:41 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: linux-kernel, Greg KH, Hotplug List

Am Donnerstag, 23. September 2004 19:05 schrieb Rolf Eike Beer:
> Jan Dittmer wrote:
> > Rolf Eike Beer wrote:
> > > Just search the archive of pcihpd-discuss@lists.sourceforge.net for
> > > dummyphp, this is the version that works. I'll rediff it soon and hope
> > > Greg will accept it this time.
> > >
> > > Message-Id to search for:
> > > <200403120947.13046@bilbo.math.uni-mannheim.de>
> >
> > You didn't read my p.s. ... I found it and it's working quite nice.
> > Already
>
> Ehm, yes. Sorry, around 1900 local time and no real breakfast until now.
>
> > discovered a bug in dv1394. Just one thing: Can you strip DUMMY- from the
> > name in /sys/bus/pci/slots/ ? It's really ugly and you can't mix
> > different hotplug drivers anyway.
>
> Sounds reasonable.

Ok, here we go. This is my current diff that I use for my tests at home. It adds
dummyphp and cleans up fakephp a lot (read: kills it). Changes from last version:

-removed some dead comments
-removed some unused instructions
-reordered allocation in add_slot to do less memory allocations if there is
 no device in slot
-changed param "usedonly" to "showunused" so it behaves like fakephp at the
 first look: if you load dummyphp without parameters there are only slots with
 devices in it.
-removed "DUMMY-" prefix to entries in /sys/bus/pci/slots/

Please send comments so I can send it for inclusion soon.

Eike

diff -x '*.o' -x '.tmp*' -Naur linux-2.6.8/drivers/pci/hotplug/Kconfig linux-2.6.9-rc2-bk/drivers/pci/hotplug/Kconfig
--- linux-2.6.8/drivers/pci/hotplug/Kconfig 2004-09-23 21:16:49.000000000 +0200
+++ linux-2.6.9-rc2-bk/drivers/pci/hotplug/Kconfig 2004-09-23 21:58:35.000000000 +0200
@@ -19,26 +19,29 @@
 
    When in doubt, say N.
 
-config HOTPLUG_PCI_FAKE
- tristate "Fake PCI Hotplug driver"
+config HOTPLUG_PCI_DUMMY
+ tristate "Dummy PCI Hotplug driver"
  depends on HOTPLUG_PCI
  help
-   Say Y here if you want to use the fake PCI hotplug driver. It can
-   be used to simulate PCI hotplug events if even if your system is
-   not PCI hotplug capable.
+   Say Y here if you want to use the dummy PCI hotplug driver. It can
+   be used to simulate PCI hotplug events even if your system is not
+   PCI hotplug capable.
 
    This driver will "emulate" removing PCI devices from the system.
    If the "power" file is written to with "0" then the specified PCI
-   device will be completely removed from the kernel.
+   device will be completely removed from the kernel. Writing "1" to
+   the power file will bring the device back.
+
+   Be careful: it claims all PCI slots in the system with a device in it.
+   There will be side effects on other hotplug drivers, so do NOT use
+   another hotplug driver at the same time.
 
    WARNING, this does NOT turn off the power to the PCI device.
    This is a "logical" removal, not a physical or electrical
    removal.
 
-   Use this module at your own risk.  You have been warned!
-
-   To compile this driver as a module, choose M here: the
-   module will be called fakephp.
+   To compile this driver as a module, choose M here: the module
+   will be called dummyphp.
 
    When in doubt, say N.
 
diff -x '*.o' -x '.tmp*' -Naur linux-2.6.8/drivers/pci/hotplug/Makefile linux-2.6.9-rc2-bk/drivers/pci/hotplug/Makefile
--- linux-2.6.8/drivers/pci/hotplug/Makefile 2004-09-23 21:16:49.000000000 +0200
+++ linux-2.6.9-rc2-bk/drivers/pci/hotplug/Makefile 2004-09-17 16:30:26.000000000 +0200
@@ -3,7 +3,7 @@
 #
 
 obj-$(CONFIG_HOTPLUG_PCI)  += pci_hotplug.o
-obj-$(CONFIG_HOTPLUG_PCI_FAKE)  += fakephp.o 
+obj-$(CONFIG_HOTPLUG_PCI_DUMMY)  += dummyphp.o
 obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o
 obj-$(CONFIG_HOTPLUG_PCI_IBM)  += ibmphp.o
 obj-$(CONFIG_HOTPLUG_PCI_ACPI)  += acpiphp.o
diff -x '*.o' -x '.tmp*' -Naur linux-2.6.8/drivers/pci/hotplug/dummyphp.c linux-2.6.9-rc2-bk/drivers/pci/hotplug/dummyphp.c
--- linux-2.6.8/drivers/pci/hotplug/dummyphp.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.9-rc2-bk/drivers/pci/hotplug/dummyphp.c 2004-09-23 23:11:23.000000000 +0200
@@ -0,0 +1,386 @@
+/*
+ * Dummy PCI Hot Plug Controller Driver
+ *
+ * Copyright (c) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
+ *
+ * Based on code from:
+ * Vladimir Kondratiev <vladimir.kondratiev@intel.com>
+ * Greg Kroah-Hartman <greg@kroah.com>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * Send feedback to <eike-kernel@sf-tec.de>
+ */
+
+/*
+ *
+ * This driver will "emulate" removing PCI devices from the system.  If
+ * the "power" file is written to with "0" then the specified PCI device
+ * will be completely removed from the kernel.
+ *
+ * WARNING, this does NOT turn off the power to the PCI device.  This is
+ * a "logical" removal, not a physical or electrical removal.
+ *
+ * Use this module at your own risk, you have been warned!
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include "pci_hotplug.h"
+#include "../pci.h"
+
+#define MY_NAME "dummyphp"
+
+#define dbg(format, arg...)     \
+ do {       \
+  if (debug)     \
+   printk(KERN_DEBUG "%s: " format, \
+    MY_NAME , ## arg);   \
+ } while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+
+/* name size which is used for entries in pcihpfs */
+#define SLOT_NAME_SIZE 14  /* {DOMAIN}-{BUS}:{DEV} */
+
+struct dummy_slot {
+ struct list_head node;
+ struct hotplug_slot *slot;
+ struct pci_dev  *dev;
+ struct pci_bus  *bus;
+ int   devfn;
+};
+
+#define DRIVER_DESC "Dummy PCI Hot Plug Controller Driver"
+
+static int debug;
+static int showunused;
+static LIST_HEAD(slot_list);
+
+MODULE_AUTHOR("Rolf Eike Beer <eike-kernel@sf-tec.de>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
+MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+module_param(debug, bool, 644);
+MODULE_PARM_DESC(showunused, "Show slots even if there is no device in it");
+module_param(showunused, bool, 644);
+
+static int enable_slot(struct hotplug_slot *slot);
+static int disable_slot(struct hotplug_slot *slot);
+static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value);
+
+static struct hotplug_slot_ops dummy_hotplug_slot_ops = {
+ .owner   = THIS_MODULE,
+ .enable_slot  = enable_slot,
+ .disable_slot  = disable_slot,
+ .get_adapter_status = get_adapter_status
+};
+
+/**
+ * dummy_release - free the memory of a slot
+ * @slot: slot pointer to remove
+ */
+static void dummy_release(struct hotplug_slot *slot)
+{
+ struct dummy_slot *dslot = slot->private;
+
+ list_del(&dslot->node);
+ kfree(dslot->slot->name);
+ kfree(dslot->slot->info);
+ kfree(dslot->slot);
+ if (dslot->dev)
+  pci_dev_put(dslot->dev);
+ kfree(dslot);
+}
+
+/**
+ * get_adapter_status - look if adapter is present in slot
+ * @hotplug_slot: slot to test value
+ * @value: status of the adapter
+ */
+static int get_adapter_status(struct hotplug_slot *slot, u8 *value)
+{
+ struct dummy_slot *dslot;
+
+ dslot = slot->private;
+
+ *value = pci_scan_slot(dslot->bus, dslot->devfn);
+ slot->info->adapter_status = *value;
+
+ return 0;
+}
+
+/**
+ * add_slot - add a new "hotplug" slot
+ * @dev: a struct pci_dev describing this slot (regardless if
+ * there is actually a device in this slot or not)
+ */
+static inline int
+add_slot(const struct pci_dev *dev)
+{
+ struct dummy_slot *dslot;
+ struct hotplug_slot *slot;
+ int retval = -ENOMEM;
+
+ dslot = kmalloc(sizeof(*dslot), GFP_KERNEL);
+ if (!dslot)
+  goto error;
+
+ dslot->bus = dev->bus;
+ dslot->devfn = dev->devfn;
+
+ dslot->dev = pci_get_slot(dslot->bus, dslot->devfn);
+
+ if (showunused || dslot->dev) {
+  retval = 0;
+  goto error_dslot;
+ }
+
+ slot = kmalloc(sizeof(*slot), GFP_KERNEL);
+ if (!slot)
+  goto error_dslot;
+
+ memset(slot, 0, sizeof(*slot));
+
+ slot->info = kmalloc(sizeof(*(slot->info)), GFP_KERNEL);
+ if (!slot->info)
+  goto error_slot;
+
+ memset(slot->info, 0, sizeof(struct hotplug_slot_info));
+
+ slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
+ slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
+
+ slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
+ if (!slot->name)
+  goto error_info;
+ slot->info->power_status = (dslot->dev != NULL);
+ slot->info->adapter_status = slot->info->power_status;
+
+ slot->ops = &dummy_hotplug_slot_ops;
+ slot->release = &dummy_release;
+ slot->private = dslot;
+
+ snprintf(slot->name, SLOT_NAME_SIZE, "%04x:%02x:%02x",
+  pci_domain_nr(dev->bus), dslot->bus->number,
+  PCI_SLOT(dslot->devfn));
+
+ retval = pci_hp_register(slot);
+ if (retval) {
+  err("pci_hp_register failed with error %d\n", retval);
+  goto error_name;
+ }
+
+ dslot->slot = slot;
+ list_add(&dslot->node, &slot_list);
+
+ return retval;
+
+error_name:
+ kfree(slot->name);
+error_info:
+ kfree(slot->info);
+error_slot:
+ kfree(slot);
+error_dslot:
+ pci_dev_put(dslot->dev);
+ kfree(dslot);
+error:
+ return retval;
+}
+
+/**
+ * scan_pci_bus - add an entry for every slot on this bus
+ * @bus: bus to scan
+ */
+static inline int
+scan_pci_bus(struct pci_bus *bus)
+{
+ int retval;
+ struct pci_dev dev;
+
+ memset(&dev, 0, sizeof(dev));
+ dev.bus = bus;
+ for (dev.devfn = 0; dev.devfn < 0x100; dev.devfn += 8) {
+  retval = add_slot(&dev);
+  if (retval)
+   break;
+ }
+ return retval;
+}
+
+/**
+ * pci_scan_buses - scan this bus and all child buses for slots
+ * @list: list of buses to scan
+ */
+static int
+pci_scan_buses(struct list_head *list)
+{
+ int retval = 0;
+ const struct list_head *l;
+
+ list_for_each(l, list) {
+  struct list_head *tmp;
+  struct list_head *next;
+  struct pci_bus *b = pci_bus_b(l);
+  int i = 0;
+
+  /* scan the list of slots to see if we have already
+   * a slot on the new bus registered */
+  list_for_each_safe(tmp, next, &slot_list) {
+   if ((list_entry(tmp, struct dummy_slot, node))->bus == b) {
+    i = 1;
+    break;
+   }
+  }
+  if (i)
+   continue;
+
+  retval = scan_pci_bus(b);
+  if (retval)
+   break;
+  retval = pci_scan_buses(&b->children);
+  if (retval)
+   break;
+ }
+ return retval;
+}
+
+/**
+ * enable_slot - power on and enable a slot
+ * @hotplug_slot: slot to enable
+ */
+static int
+enable_slot(struct hotplug_slot *hotplug_slot)
+{
+ struct dummy_slot *dslot = hotplug_slot->private;
+ int num, result = -ENODEV;
+
+ dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+ /* exit if device in slot is already active */
+ if (dslot->dev != NULL)
+  return 0;
+
+ dslot->dev = pci_get_slot(dslot->bus, dslot->devfn);
+
+ /* No pci device, we need to create it then */
+ if (dslot->dev == NULL) {
+  num = pci_scan_slot(dslot->bus, dslot->devfn);
+  if (!num) {
+   dbg("INFO: enable_slot called on empty slot\n");
+   return result;
+  }
+
+  pci_bus_add_devices(dslot->bus);
+
+  dslot->dev = pci_get_slot(dslot->bus, dslot->devfn);
+  /* pci_get_slot fails but we have found devices in this slot before? */
+  WARN_ON(dslot->dev == NULL);
+ }
+
+ if (dslot->dev->subordinate)
+  result = pci_scan_buses(&(dslot->dev->subordinate->node));
+ else
+  result = 0;
+
+ return result;
+}
+
+/**
+ * disable_subordinate - remove hotplug slot entry of device on this bus
+ * @bus: PCI bus to remove (including all children)
+ */
+static void
+disable_subordinate(struct pci_bus *bus)
+{
+ struct list_head *tmp;
+ struct list_head *next;
+ struct dummy_slot *dslot;
+
+	list_for_each_safe(tmp, next, &slot_list) {
+		dslot = list_entry(tmp, struct dummy_slot, node);
+		if (dslot->bus == bus) {
+			if (dslot->dev != NULL)
+				if (dslot->dev->subordinate)
+			/* FIXME: look if this bus can be reached through a
+			   different bridge. If yes, don't disable it */
+					disable_subordinate(dslot->dev->subordinate);
+			/* no need to disable the devices itself, this will be
+			   done by pci_remove_bus_device */
+			pci_hp_deregister(dslot->slot);
+		}
+	}
+}
+
+/**
+ * disable_slot - disable any adapter in this slot
+ * @slot: slot to disable
+ */
+static int
+disable_slot(struct hotplug_slot *slot)
+{
+	struct dummy_slot *dslot = slot->private;
+	struct pci_dev *dev = dslot->dev;
+	int i;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, slot->name);
+
+	if (!dev) {
+		dbg("No device in slot, exiting");
+		return -ENODEV;
+	}
+
+	/* check if this is a PCI bridge and remove devices on
+	   sub-buses first */
+	if (dev->subordinate)
+		disable_subordinate(dev->subordinate);
+
+	dslot->dev = NULL;
+ pci_dev_put(dev);
+
+ /* remove the device from the pci core */
+ info("Slot %s removed\n", pci_name(dev));
+
+ for (i = 0; i < 8; i++) {
+  dev = pci_get_slot(dslot->bus, dslot->devfn + i);
+  if (dev)
+   pci_remove_bus_device(dev);
+ }
+
+ slot->info->power_status = 0;
+
+ return 0;
+}
+
+static int __init
+dummyphp_init(void)
+{
+ info(DRIVER_DESC "\n");
+
+ return pci_scan_buses(&pci_root_buses);
+}
+
+static void __exit
+dummyphp_exit(void)
+{
+ struct list_head *tmp;
+ struct list_head *next;
+ struct dummy_slot *dslot;
+
+ list_for_each_safe(tmp, next, &slot_list) {
+  dslot = list_entry(tmp, struct dummy_slot, node);
+  pci_hp_deregister(dslot->slot);
+ }
+}
+
+module_init(dummyphp_init);
+module_exit(dummyphp_exit);
diff -x '*.o' -x '.tmp*' -Naur linux-2.6.8/drivers/pci/hotplug/fakephp.c linux-2.6.9-rc2-bk/drivers/pci/hotplug/fakephp.c
--- linux-2.6.8/drivers/pci/hotplug/fakephp.c 2004-08-14 07:37:25.000000000 +0200
+++ linux-2.6.9-rc2-bk/drivers/pci/hotplug/fakephp.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,232 +0,0 @@
-/*
- * Fake PCI Hot Plug Controller Driver
- *
- * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 2003 IBM Corp.
- * Copyright (C) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
- *
- * Based on ideas and code from:
- *  Vladimir Kondratiev <vladimir.kondratiev@intel.com>
- * Rolf Eike Beer <eike-kernel@sf-tec.de>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2 of the License.
- *
- * Send feedback to <greg@kroah.com>
- */
-
-/*
- *
- * This driver will "emulate" removing PCI devices from the system.  If
- * the "power" file is written to with "0" then the specified PCI device
- * will be completely removed from the kernel.
- *
- * WARNING, this does NOT turn off the power to the PCI device.  This is
- * a "logical" removal, not a physical or electrical removal.
- *
- * Use this module at your own risk, you have been warned!
- *
- * Enabling PCI devices is left as an exercise for the reader...
- *
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include "pci_hotplug.h"
-#include "../pci.h"
-
-#if !defined(CONFIG_HOTPLUG_PCI_FAKE_MODULE)
- #define MY_NAME "fakephp"
-#else
- #define MY_NAME THIS_MODULE->name
-#endif
-
-#define dbg(format, arg...)     \
- do {       \
-  if (debug)     \
-   printk(KERN_DEBUG "%s: " format, \
-    MY_NAME , ## arg);   \
- } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
-
-#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
-#define DRIVER_DESC "Fake PCI Hot Plug Controller Driver"
-
-struct dummy_slot {
- struct list_head node;
- struct hotplug_slot *slot;
- struct pci_dev *dev;
-};
-
-static int debug;
-static LIST_HEAD(slot_list);
-
-static int enable_slot (struct hotplug_slot *slot);
-static int disable_slot (struct hotplug_slot *slot);
-
-static struct hotplug_slot_ops dummy_hotplug_slot_ops = {
- .owner   = THIS_MODULE,
- .enable_slot  = enable_slot,
- .disable_slot  = disable_slot,
-};
-
-static void dummy_release(struct hotplug_slot *slot)
-{
- struct dummy_slot *dslot = slot->private;
-
- list_del(&dslot->node);
- kfree(dslot->slot->info);
- kfree(dslot->slot);
- pci_dev_put(dslot->dev);
- kfree(dslot);
-}
-
-static int add_slot(struct pci_dev *dev)
-{
- struct dummy_slot *dslot;
- struct hotplug_slot *slot;
- int retval = -ENOMEM;
-
- slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
- if (!slot)
-  goto error;
- memset(slot, 0, sizeof(*slot));
-
- slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
-	if (!slot->info)
-		goto error_slot;
-	memset(slot->info, 0, sizeof(struct hotplug_slot_info));
-
-	slot->info->power_status = 1;
-	slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
-	slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
-
-	slot->name = &dev->dev.bus_id[0];
-	dbg("slot->name = %s\n", slot->name);
-
-	dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL);
-	if (!dslot)
-		goto error_info;
-
-	slot->ops = &dummy_hotplug_slot_ops;
-	slot->release = &dummy_release;
-	slot->private = dslot;
-
-	retval = pci_hp_register(slot);
-	if (retval) {
-		err("pci_hp_register failed with error %d\n", retval);
-		goto error_dslot;
-	}
-
-	dslot->slot = slot;
-	dslot->dev = pci_dev_get(dev);
-	list_add (&dslot->node, &slot_list);
-	return retval;
-
-error_dslot:
-	kfree(dslot);
-error_info:
-	kfree(slot->info);
-error_slot:
-	kfree(slot);
-error:
-	return retval;
-}
-
-static int __init pci_scan_buses(void)
-{
-	struct pci_dev *dev = NULL;
-	int retval = 0;
-
-	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		retval = add_slot(dev);
-		if (retval) {
-			pci_dev_put(dev);
-			break;
-		}
-	}
-
-	return retval;
-}
-
-static void remove_slot(struct dummy_slot *dslot)
-{
-	int retval;
-
-	dbg("removing slot %s\n", dslot->slot->name);
-	retval = pci_hp_deregister(dslot->slot);
-	if (retval)
-		err("Problem unregistering a slot %s\n", dslot->slot->name);
-}
-
-static int enable_slot(struct hotplug_slot *hotplug_slot)
-{
-	return -ENODEV;
-}
-
-static int disable_slot(struct hotplug_slot *slot)
-{
-	struct dummy_slot *dslot;
-
-	if (!slot)
-		return -ENODEV;
-	dslot = slot->private;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, slot->name);
-
-	/* don't disable bridged devices just yet, we can't handle them easily... */
-	if (dslot->dev->subordinate) {
-		err("Can't remove PCI devices with other PCI devices behind it yet.\n");
-		return -ENODEV;
-	}
-
-	/* remove the device from the pci core */
-	pci_remove_bus_device(dslot->dev);
-
-	/* blow away this sysfs entry and other parts. */
-	remove_slot(dslot);
-
-	return 0;
-}
-
-static void cleanup_slots (void)
-{
- struct list_head *tmp;
- struct list_head *next;
- struct dummy_slot *dslot;
-
- list_for_each_safe (tmp, next, &slot_list) {
-  dslot = list_entry (tmp, struct dummy_slot, node);
-  remove_slot(dslot);
- }
- 
-}
-
-static int __init dummyphp_init(void)
-{
- info(DRIVER_DESC "\n");
-
- return pci_scan_buses();
-}
-
-
-static void __exit dummyphp_exit(void)
-{
- cleanup_slots();
-}
-
-module_init(dummyphp_init);
-module_exit(dummyphp_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-

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

* Re: Is there a user space pci rescan method?
  2004-09-24 10:41             ` Rolf Eike Beer
@ 2004-09-24 11:42               ` Jan Dittmer
  2004-09-24 12:12                 ` Rolf Eike Beer
  2004-09-24 12:40               ` Jan Dittmer
  1 sibling, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-09-24 11:42 UTC (permalink / raw)
  To: Rolf Eike Beer; +Cc: linux-kernel, Greg KH, Hotplug List

Rolf Eike Beer wrote:
> Ok, here we go. This is my current diff that I use for my tests at home. It adds
> dummyphp and cleans up fakephp a lot (read: kills it). Changes from last version:
> 
> -removed some dead comments
> -removed some unused instructions
> -reordered allocation in add_slot to do less memory allocations if there is
>  no device in slot
> -changed param "usedonly" to "showunused" so it behaves like fakephp at the
>  first look: if you load dummyphp without parameters there are only slots with
>  devices in it.
> -removed "DUMMY-" prefix to entries in /sys/bus/pci/slots/
> 
> Please send comments so I can send it for inclusion soon.

Well, first of all I think you should just submit a patch to add dummyphp and not
removing fakephp in the same step. Also you somehow mis-copied the patch to
your mail app - most (not all) tabs are converted to one space (or is it just
thunderbird displaying the mail?). Can you resend it? Then I'll give it a try.
Greg wrote in another mail that the 'proper' way of 'powering up' device slots should
be to rescan the entire bus. I don't know, your approach certainly seems easier, but you
are bound to either display all pci slots which may come to live or just the ones
in the system already, which means you cannot rescan slots which weren't equipped
on boot up. So perhaps adding a rescan method to fakephp is indeed cleaner.

Jan

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

* Re: Is there a user space pci rescan method?
  2004-09-24 11:42               ` Jan Dittmer
@ 2004-09-24 12:12                 ` Rolf Eike Beer
  2004-09-24 12:16                   ` Jan Dittmer
  0 siblings, 1 reply; 31+ messages in thread
From: Rolf Eike Beer @ 2004-09-24 12:12 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: linux-kernel, Greg KH, Hotplug List

Am Freitag, 24. September 2004 13:42 schrieben Sie:
> Rolf Eike Beer wrote:
> > Ok, here we go. This is my current diff that I use for my tests at home.
> > It adds dummyphp and cleans up fakephp a lot (read: kills it). Changes
> > from last version:
> >
> > -removed some dead comments
> > -removed some unused instructions
> > -reordered allocation in add_slot to do less memory allocations if there
> > is no device in slot
> > -changed param "usedonly" to "showunused" so it behaves like fakephp at
> > the first look: if you load dummyphp without parameters there are only
> > slots with devices in it.
> > -removed "DUMMY-" prefix to entries in /sys/bus/pci/slots/
> >
> > Please send comments so I can send it for inclusion soon.
>
> Well, first of all I think you should just submit a patch to add dummyphp
> and not removing fakephp in the same step. Also you somehow mis-copied the

I said it's my test diff and that I'll redo it for submission ;)

> patch to your mail app - most (not all) tabs are converted to one space (or
> is it just thunderbird displaying the mail?). Can you resend it? Then I'll

Yes, looks like KMail has eaten it. Hey KDE guys, is this intentional or was 
this my fault?

You can get it from http://opensource.sf-tec.de/kernel/fake_vs_dummy.diff

> give it a try. Greg wrote in another mail that the 'proper' way of
> 'powering up' device slots should be to rescan the entire bus. I don't
> know, your approach certainly seems easier, but you are bound to either
> display all pci slots which may come to live or just the ones in the system
> already, which means you cannot rescan slots which weren't equipped on boot
> up. So perhaps adding a rescan method to fakephp is indeed cleaner.

This is for simulating hotplug events. I don't know how there could be a slot 
where you put in a device that has not been there on system bootup. Ok, you 
can trigger such a case by disabling a slot, rmmod dummyphp, modprobe 
dummyphp again. Greg didn't like dummyphp to display all logical slots even 
if there is no device in them - which I can understand, under normal 
circumstances you will never have a use for this extra slots. If you want 
them just do "modprobe dummyphp showunused=1" and you'll get them all.

Normally you will just remove and bring back one or two cards in the system 
(e.g. your NIC or sound card, depending on xmms or irc being on top of your 
priority list *g*). So from my point of view it's a good idea to keep the 
slot dirs on remove so you can just go back in your command history and 
replace 0 with 1 to get the device back. I don't see why bus structure or 
whatever may ever change so rescanning the whole bus is IMHO a bit overkill.

Adding a rescan file is also extra work, the power file is there 
automagically ;)

Eike

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

* Re: Is there a user space pci rescan method?
  2004-09-24 12:12                 ` Rolf Eike Beer
@ 2004-09-24 12:16                   ` Jan Dittmer
  2004-09-24 12:32                     ` Rolf Eike Beer
  2004-09-24 13:09                     ` [Pcihpd-discuss] Re: Is there a user space pci rescan method? Matthew Wilcox
  0 siblings, 2 replies; 31+ messages in thread
From: Jan Dittmer @ 2004-09-24 12:16 UTC (permalink / raw)
  To: Rolf Eike Beer; +Cc: linux-kernel, Greg KH, Hotplug List

Rolf Eike Beer wrote:
> Normally you will just remove and bring back one or two cards in the system 
> (e.g. your NIC or sound card, depending on xmms or irc being on top of your 
> priority list *g*). So from my point of view it's a good idea to keep the 
> slot dirs on remove so you can just go back in your command history and 
> replace 0 with 1 to get the device back. I don't see why bus structure or 
> whatever may ever change so rescanning the whole bus is IMHO a bit overkill.

My point was, I load dummyphp with showunused=0 and only get dirs for the
slots with devices in them. Now I decide to put a network card (or whatever
I have to spare) in an empty slot, hope that the system doesn't reboot
immediately, and voila I don't have any /sys/bus/pci/slots dir to enable
the slot and have to reboot nevertheless. Or does the pci system a rescan
if I reinsert the module?

Thanks,

Jan

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

* Re: Is there a user space pci rescan method?
  2004-09-24 12:16                   ` Jan Dittmer
@ 2004-09-24 12:32                     ` Rolf Eike Beer
  2004-09-24 14:55                       ` Greg KH
  2004-09-24 13:09                     ` [Pcihpd-discuss] Re: Is there a user space pci rescan method? Matthew Wilcox
  1 sibling, 1 reply; 31+ messages in thread
From: Rolf Eike Beer @ 2004-09-24 12:32 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: linux-kernel, Greg KH, Hotplug List

Am Freitag, 24. September 2004 14:16 schrieben Sie:
> Rolf Eike Beer wrote:
> > Normally you will just remove and bring back one or two cards in the
> > system (e.g. your NIC or sound card, depending on xmms or irc being on
> > top of your priority list *g*). So from my point of view it's a good idea
> > to keep the slot dirs on remove so you can just go back in your command
> > history and replace 0 with 1 to get the device back. I don't see why bus
> > structure or whatever may ever change so rescanning the whole bus is IMHO
> > a bit overkill.
>
> My point was, I load dummyphp with showunused=0 and only get dirs for the
> slots with devices in them. Now I decide to put a network card (or whatever
> I have to spare) in an empty slot, hope that the system doesn't reboot
> immediately, and voila I don't have any /sys/bus/pci/slots dir to enable
> the slot and have to reboot nevertheless. Or does the pci system a rescan
> if I reinsert the module?

In this case you have to "rmmod dummyphp; modprobe dummyphp showunused=1" to 
get all slots and try to enable the device. We have tested it once with a 
special PCI debugging board where we can electrically disable the PCI bus so 
we don't kill our hardware. The problem was that on reenabling a interrupt 
storm killed the machine, I don't remember the exact problem. IIRC it looked 
like the kernel found the device but the PCI bridge got confused by the new 
device (or something like this). I don't know if there is a way to survive 
this situation as the bridges in "normal" hardware are not hotplug aware. 
Greg?

If there is a way I will try to impleement it, but for now this is beyound my 
knowledge.

Eike

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

* Re: Is there a user space pci rescan method?
  2004-09-24 10:41             ` Rolf Eike Beer
  2004-09-24 11:42               ` Jan Dittmer
@ 2004-09-24 12:40               ` Jan Dittmer
  2004-09-24 12:59                 ` Rolf Eike Beer
  1 sibling, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-09-24 12:40 UTC (permalink / raw)
  To: Rolf Eike Beer; +Cc: linux-kernel, Greg KH, Hotplug List

Rolf Eike Beer wrote:
> -changed param "usedonly" to "showunused" so it behaves like fakephp at the
>  first look: if you load dummyphp without parameters there are only slots with
>  devices in it.

Well, know I get only entries for all devices I don't have!

> + dslot->dev = pci_get_slot(dslot->bus, dslot->devfn);
> +
> + if (showunused || dslot->dev) {
> +  retval = 0;
> +  goto error_dslot;
> + }

This should probably be !showunused || !dslot->dev ?

Jan

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

* Re: Is there a user space pci rescan method?
  2004-09-24 12:40               ` Jan Dittmer
@ 2004-09-24 12:59                 ` Rolf Eike Beer
  0 siblings, 0 replies; 31+ messages in thread
From: Rolf Eike Beer @ 2004-09-24 12:59 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: linux-kernel, Greg KH, Hotplug List

Am Freitag, 24. September 2004 14:40 schrieben Sie:
> Rolf Eike Beer wrote:
> > -changed param "usedonly" to "showunused" so it behaves like fakephp at
> > the first look: if you load dummyphp without parameters there are only
> > slots with devices in it.
>
> Well, know I get only entries for all devices I don't have!

There was a device mask but I decided this was too ugly and ripped it out. 
Maybe it would make sense to have a parameter with an array of buses you want 
to see completely or something like this.

> > + dslot->dev = pci_get_slot(dslot->bus, dslot->devfn);
> > +
> > + if (showunused || dslot->dev) {
> > +  retval = 0;
> > +  goto error_dslot;
> > + }
>
> This should probably be !showunused || !dslot->dev ?

Yes. Error in boolean simplification.

Eike

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

* Re: [Pcihpd-discuss] Re: Is there a user space pci rescan method?
  2004-09-24 12:16                   ` Jan Dittmer
  2004-09-24 12:32                     ` Rolf Eike Beer
@ 2004-09-24 13:09                     ` Matthew Wilcox
  2004-09-24 13:18                       ` Rolf Eike Beer
  1 sibling, 1 reply; 31+ messages in thread
From: Matthew Wilcox @ 2004-09-24 13:09 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: Rolf Eike Beer, linux-kernel, Greg KH, Hotplug List

On Fri, Sep 24, 2004 at 02:16:09PM +0200, Jan Dittmer wrote:
> My point was, I load dummyphp with showunused=0 and only get dirs for the
> slots with devices in them. Now I decide to put a network card (or whatever
> I have to spare) in an empty slot, hope that the system doesn't reboot
> immediately, and voila I don't have any /sys/bus/pci/slots dir to enable
> the slot and have to reboot nevertheless. Or does the pci system a rescan
> if I reinsert the module?

That is DANGEROUS and WILL DESTROY YOUR SYSTEM.  Under no circumstances
should we be encouraging people to do that.

-- 
"Next the statesmen will invent cheap lies, putting the blame upon 
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince 
himself that the war is just, and will thank God for the better sleep 
he enjoys after this process of grotesque self-deception." -- Mark Twain

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

* Re: [Pcihpd-discuss] Re: Is there a user space pci rescan method?
  2004-09-24 13:09                     ` [Pcihpd-discuss] Re: Is there a user space pci rescan method? Matthew Wilcox
@ 2004-09-24 13:18                       ` Rolf Eike Beer
  0 siblings, 0 replies; 31+ messages in thread
From: Rolf Eike Beer @ 2004-09-24 13:18 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: Jan Dittmer, linux-kernel, Greg KH, Hotplug List

Am Freitag, 24. September 2004 15:09 schrieb Matthew Wilcox:
> On Fri, Sep 24, 2004 at 02:16:09PM +0200, Jan Dittmer wrote:
> > My point was, I load dummyphp with showunused=0 and only get dirs for the
> > slots with devices in them. Now I decide to put a network card (or
> > whatever I have to spare) in an empty slot, hope that the system doesn't
> > reboot immediately, and voila I don't have any /sys/bus/pci/slots dir to
> > enable the slot and have to reboot nevertheless. Or does the pci system a
> > rescan if I reinsert the module?
>
> That is DANGEROUS and WILL DESTROY YOUR SYSTEM.  Under no circumstances
> should we be encouraging people to do that.

Yes, and that's why there a big comments as well in the Kconfig help as well 
as in the source of both dummyphp and fakephp.

Eike

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

* Re: Is there a user space pci rescan method?
  2004-09-24 12:32                     ` Rolf Eike Beer
@ 2004-09-24 14:55                       ` Greg KH
  2004-09-27  9:14                         ` Rolf Eike Beer
  2004-10-10  0:13                         ` Jan Dittmer
  0 siblings, 2 replies; 31+ messages in thread
From: Greg KH @ 2004-09-24 14:55 UTC (permalink / raw)
  To: Rolf Eike Beer; +Cc: Jan Dittmer, linux-kernel, Hotplug List

On Fri, Sep 24, 2004 at 02:32:06PM +0200, Rolf Eike Beer wrote:
> Am Freitag, 24. September 2004 14:16 schrieben Sie:
> > Rolf Eike Beer wrote:
> > > Normally you will just remove and bring back one or two cards in the
> > > system (e.g. your NIC or sound card, depending on xmms or irc being on
> > > top of your priority list *g*). So from my point of view it's a good idea
> > > to keep the slot dirs on remove so you can just go back in your command
> > > history and replace 0 with 1 to get the device back. I don't see why bus
> > > structure or whatever may ever change so rescanning the whole bus is IMHO
> > > a bit overkill.
> >
> > My point was, I load dummyphp with showunused=0 and only get dirs for the
> > slots with devices in them. Now I decide to put a network card (or whatever
> > I have to spare) in an empty slot, hope that the system doesn't reboot
> > immediately, and voila I don't have any /sys/bus/pci/slots dir to enable
> > the slot and have to reboot nevertheless. Or does the pci system a rescan
> > if I reinsert the module?
> 
> In this case you have to "rmmod dummyphp; modprobe dummyphp showunused=1" to 
> get all slots and try to enable the device. We have tested it once with a 
> special PCI debugging board where we can electrically disable the PCI bus so 
> we don't kill our hardware. The problem was that on reenabling a interrupt 
> storm killed the machine, I don't remember the exact problem. IIRC it looked 
> like the kernel found the device but the PCI bridge got confused by the new 
> device (or something like this). I don't know if there is a way to survive 
> this situation as the bridges in "normal" hardware are not hotplug aware. 
> Greg?

Hm, don't know, but that's the whole reason people want this, so it
should work :)

The main reason I don't like showing _all_ possible pci devices like
dummyphp does is that it doesn't handle adding a new device (like you
just said), and the fact that you forgot to handle pci domains.  If you
add support for PCI domains, then the list of files in that directory
will pretty much be unusable.

Please just add the "rescan" support to fakephp, and everyone will be
happy...

thanks,

greg k-h

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

* Re: Is there a user space pci rescan method?
  2004-09-24 14:55                       ` Greg KH
@ 2004-09-27  9:14                         ` Rolf Eike Beer
  2004-10-10  0:13                         ` Jan Dittmer
  1 sibling, 0 replies; 31+ messages in thread
From: Rolf Eike Beer @ 2004-09-27  9:14 UTC (permalink / raw)
  To: Greg KH; +Cc: Jan Dittmer, linux-kernel, Hotplug List

> > to get all slots and try to enable the device. We have tested it once
> > with a special PCI debugging board where we can electrically disable the
> > PCI bus so we don't kill our hardware. The problem was that on reenabling
> > a interrupt storm killed the machine, I don't remember the exact problem.
> > IIRC it looked like the kernel found the device but the PCI bridge got
> > confused by the new device (or something like this). I don't know if
> > there is a way to survive this situation as the bridges in "normal"
> > hardware are not hotplug aware. Greg?
>
> Hm, don't know, but that's the whole reason people want this, so it
> should work :)

IMHO they want it for testing logical removal, hot removal without hardware 
support is just too dangerous to test with dummyphp. Or what am I missing?

> The main reason I don't like showing _all_ possible pci devices like
> dummyphp does is that it doesn't handle adding a new device (like you
> just said), and the fact that you forgot to handle pci domains.  If you
> add support for PCI domains, then the list of files in that directory
> will pretty much be unusable.

Ehm? Did you read the code? I use the PCI domains of the slots and buses. And 
by default there are only slots with devices in it shown now.

> Please just add the "rescan" support to fakephp, and everyone will be
> happy...

That can't be. I hate fakephp ;)

Eike

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

* Re: Is there a user space pci rescan method?
  2004-09-24 14:55                       ` Greg KH
  2004-09-27  9:14                         ` Rolf Eike Beer
@ 2004-10-10  0:13                         ` Jan Dittmer
  2004-10-10  0:59                           ` Jan Dittmer
  1 sibling, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-10-10  0:13 UTC (permalink / raw)
  To: Greg KH; +Cc: Rolf Eike Beer, linux-kernel, Hotplug List

[-- Attachment #1: Type: text/plain, Size: 785 bytes --]

Greg KH wrote:
> Please just add the "rescan" support to fakephp, and everyone will be
> happy...

Well, I started to work on this for fun. What I currently have is a
stand-alone module which rescans the pci bus on insert and enables
previously disabled devices. This works (at least with my ieee1394 port).
Problem is, that fakephp does not get notified about this new pci device
and no new file is created in /sys/bus/pci/slots. So I'm going to add
this rescan functionality directly to fakephp.
Question is: where? My current idea is a fake hotplug slot "rescan" in
/sys/bus/pci/slots , where you can write "1" into the "power" attribute.
FWIW I've attached the standalone module and a kernel patch which rips
out the pci_bus_add_device functionality from pci_bus_add_devices.

Jan

[-- Attachment #2: pci_bus_add_device.patch --]
[-- Type: text/x-patch, Size: 1692 bytes --]

--- linus/include/linux/pci.h	2004-10-06 19:58:35.000000000 +0200
+++ pcirescan/include/linux/pci.h	2004-10-10 01:55:41.000000000 +0200
@@ -704,6 +704,7 @@
 int pci_scan_slot(struct pci_bus *bus, int devfn);
 struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
 unsigned int pci_scan_child_bus(struct pci_bus *bus);
+void pci_bus_add_device(struct pci_dev *dev);
 void pci_bus_add_devices(struct pci_bus *bus);
 void pci_name_device(struct pci_dev *dev);
 char *pci_class_name(u32 class);
diff -ur linus/drivers/pci/bus.c pcirescan/drivers/pci/bus.c
--- linus/drivers/pci/bus.c	2004-05-10 10:06:44.000000000 +0200
+++ pcirescan/drivers/pci/bus.c	2004-10-10 01:29:50.000000000 +0200
@@ -69,6 +69,20 @@
 }
 
 /**
+ * add a single device
+ */
+void __devinit pci_bus_add_device(struct pci_dev *dev) {
+	device_add(&dev->dev);
+
+	spin_lock(&pci_bus_lock);
+	list_add_tail(&dev->global_list, &pci_devices);
+	spin_unlock(&pci_bus_lock);
+
+	pci_proc_attach_device(dev);
+	pci_create_sysfs_dev_files(dev);
+}
+
+/**
  * pci_bus_add_devices - insert newly discovered PCI devices
  * @bus: bus to check for new devices
  *
@@ -91,16 +105,7 @@
 		 */
 		if (!list_empty(&dev->global_list))
 			continue;
-
-		device_add(&dev->dev);
-
-		spin_lock(&pci_bus_lock);
-		list_add_tail(&dev->global_list, &pci_devices);
-		spin_unlock(&pci_bus_lock);
-
-		pci_proc_attach_device(dev);
-		pci_create_sysfs_dev_files(dev);
-
+		pci_bus_add_device(dev);
 	}
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -136,5 +141,6 @@
 }
 
 EXPORT_SYMBOL(pci_bus_alloc_resource);
+EXPORT_SYMBOL(pci_bus_add_device);
 EXPORT_SYMBOL(pci_bus_add_devices);
 EXPORT_SYMBOL(pci_enable_bridges);

[-- Attachment #3: Makefile --]
[-- Type: text/plain, Size: 202 bytes --]

ifneq ($(KERNELRELEASE),)

obj-m	:= pcirescan.o

else

KDIR	:= /lib/modules/$(shell uname -r)/build
# KDIR := ../pcirescan
PWD	:= $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
endif

[-- Attachment #4: pcirescan.c --]
[-- Type: text/x-csrc, Size: 3174 bytes --]

/**
 * rescan the pci bus on insert
 * Jan Dittmer <jdittmer@ppp0.net>
 *
 * heavily based on a similar module from
 * Vladimir Kondratiev, vladimir.kondratiev@intel.com
 */
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/errno.h>

/**
 * Rescan slot.
 * First, determine whether card in the slot has changed. It is
 * done by compare of old and actual devices for function 0.
 * If change detected, old device(s) removed, other functions
 * scanned if it is multi-function dev, new devices inserted.
 * 
 * @param temp   Device template. Should be set: bus and devfn.
 * @return Device for function 0
 */
void pci_rescan_slot(struct pci_dev *temp)
{
	struct pci_bus *bus = temp->bus;
	struct pci_dev* old_dev = pci_find_slot(bus->number,temp->devfn);
	struct pci_dev *dev = NULL;
	int func = 0;
	int new_multi = 0;  /* new multifunction device */
	u8 hdr_type;
	/* function 0 */
	if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
		temp->hdr_type = hdr_type & 0x7f;
		new_multi=hdr_type & 0x80;
		if (!old_dev) {
			dev = pci_scan_single_device(bus, temp->devfn);
			if (dev) {
				printk("Found new device on %s function %x:%x %x\n",
						bus->name, temp->devfn >> 3,
						temp->devfn & 7,
						hdr_type);
				pci_bus_add_device(dev);
			}
		}
		if (new_multi) { /* continue scanning for other functions */
/*			printk("Scanning subfunctions\n"); */
			for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
				//	printk("%x\n", func);
				if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
					continue;
				temp->hdr_type = hdr_type & 0x7f;

				old_dev = pci_find_slot(bus->number, temp->devfn);
				if (!old_dev) {
					dev = pci_scan_single_device(bus, temp->devfn);
					if (dev) {
						printk("Found new device on %s function %x:%x %x\n",
								bus->name, temp->devfn >> 3,
								temp->devfn & 7,
								hdr_type);
						printk("Prettyname %s\n", dev->pretty_name);
						// from drivers/pci/bus.c, pci_bus_add_devices
						pci_bus_add_device(dev);
					}
				} 
			}
		}
	}
}


/**
 * Rescan PCI bus.
 * Assumed, some slots may have changed its content.
 * Find old information about each slot and the new one.
 * If they match, do nothing. Otherwise,
 * remove/insert proper devices.
 * 
 * @param bus
 */
static void pci_rescan_bus(const struct pci_bus *bus)
{
	unsigned int devfn;
	struct pci_dev dev0;

	memset(&dev0, 0, sizeof(dev0));
	dev0.bus = (struct pci_bus*)bus;
	dev0.sysdata = bus->sysdata;
	for (devfn = 0; devfn < 0x100; devfn += 8) {
		dev0.devfn = devfn;
		pci_rescan_slot(&dev0);
	}
}

static void pci_rescan_buses(const struct list_head *list)
{
	const struct list_head *l;
	list_for_each(l,list) {
		const struct pci_bus *b = pci_bus_b(l);
		/*
		printk("Scanning Bus %d:%d:%d, %s\n", b->number,
				b->primary, b->secondary, b->name);
		*/
		pci_rescan_bus(b);
		pci_rescan_buses(&b->children);
	}
}



static int pci_rescan_init(void)
{
	pci_rescan_buses(&pci_root_buses);
	return -ENODEV;
}

static void pci_rescan_exit(void)
{}


module_init(pci_rescan_init);
module_exit(pci_rescan_exit);

MODULE_DESCRIPTION("Do PCI bus rescan");
MODULE_AUTHOR("jdi");


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

* Re: Is there a user space pci rescan method?
  2004-10-10  0:13                         ` Jan Dittmer
@ 2004-10-10  0:59                           ` Jan Dittmer
  2004-10-10 13:45                             ` Jan Dittmer
  0 siblings, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-10-10  0:59 UTC (permalink / raw)
  To: Greg KH; +Cc: Rolf Eike Beer, linux-kernel, Hotplug List

[-- Attachment #1: Type: text/plain, Size: 1087 bytes --]

Jan Dittmer wrote:
> Greg KH wrote:
> 
>>Please just add the "rescan" support to fakephp, and everyone will be
>>happy...
> 
> 
> Well, I started to work on this for fun. What I currently have is a
> stand-alone module which rescans the pci bus on insert and enables
> previously disabled devices. This works (at least with my ieee1394 port).
> Problem is, that fakephp does not get notified about this new pci device
> and no new file is created in /sys/bus/pci/slots. So I'm going to add
> this rescan functionality directly to fakephp.
> Question is: where? My current idea is a fake hotplug slot "rescan" in
> /sys/bus/pci/slots , where you can write "1" into the "power" attribute.
> FWIW I've attached the standalone module and a kernel patch which rips
> out the pci_bus_add_device functionality from pci_bus_add_devices.

Well, here is a quick & dirty hack, which adds this function to
enable_slot in fakephp. So if you write "1" in the power attribute of
any slot, the whole bus gets rescanned (you still need the
pci_bus_add_device.patch from the previous mail).

Thanks,

Jan

[-- Attachment #2: fakephp-rescan-on-enable.patch --]
[-- Type: text/x-patch, Size: 3245 bytes --]

diff -ur linus/drivers/pci/hotplug/fakephp.c pcirescan/drivers/pci/hotplug/fakephp.c
--- linus/drivers/pci/hotplug/fakephp.c	2004-01-09 07:59:45.000000000 +0100
+++ pcirescan/drivers/pci/hotplug/fakephp.c	2004-10-10 02:53:05.000000000 +0200
@@ -165,8 +165,111 @@
 		err("Problem unregistering a slot %s\n", dslot->slot->name);
 }
 
+/**
+ * Rescan slot.
+ * First, determine whether card in the slot has changed. It is
+ * done by compare of old and actual devices for function 0.
+ * If change detected, old device(s) removed, other functions
+ * scanned if it is multi-function dev, new devices inserted.
+ * 
+ * @param temp   Device template. Should be set: bus and devfn.
+ * @return Device for function 0
+ */
+static void pci_rescan_slot(struct pci_dev *temp)
+{
+	struct pci_bus *bus = temp->bus;
+	struct pci_dev* old_dev = pci_find_slot(bus->number, temp->devfn);
+	struct pci_dev *dev = NULL;
+	int func = 0;
+	int new_multi = 0;  /* new multifunction device */
+	u8 hdr_type;
+	if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
+		temp->hdr_type = hdr_type & 0x7f;
+		new_multi=hdr_type & 0x80;
+		if (!old_dev) {
+			dev = pci_scan_single_device(bus, temp->devfn);
+			if (dev) {
+				printk("Found new device on %s function %x:%x %x\n",
+						bus->name, temp->devfn >> 3,
+						temp->devfn & 7,
+						hdr_type);
+				pci_bus_add_device(dev);
+				add_slot(dev);
+			}
+		}
+		if (new_multi) { /* continue scanning for other functions */
+			for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
+				//	printk("%x\n", func);
+				if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
+					continue;
+				temp->hdr_type = hdr_type & 0x7f;
+
+				old_dev = pci_find_slot(bus->number, temp->devfn);
+				if (!old_dev) {
+					dev = pci_scan_single_device(bus, temp->devfn);
+					if (dev) {
+						printk("Found new device on %s function %x:%x %x\n",
+								bus->name, temp->devfn >> 3,
+								temp->devfn & 7,
+								hdr_type);
+						// from drivers/pci/bus.c, pci_bus_add_devices
+						pci_bus_add_device(dev);
+						// add fakephp slot
+						add_slot(dev);
+					}
+				} 
+			}
+		}
+	}
+}
+
+
+/**
+ * Rescan PCI bus.
+ * Assumed, some slots may have changed its content.
+ * Find old information about each slot and the new one.
+ * If they match, do nothing. Otherwise,
+ * remove/insert proper devices.
+ * 
+ * @param bus
+ */
+static void pci_rescan_bus(const struct pci_bus *bus)
+{
+	unsigned int devfn;
+	struct pci_dev *dev;
+	dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+	if (!dev)
+		return;
+
+	memset(dev, 0, sizeof(dev));
+	dev->bus = (struct pci_bus*)bus;
+	dev->sysdata = bus->sysdata;
+	for (devfn = 0; devfn < 0x100; devfn += 8) {
+		dev->devfn = devfn;
+		pci_rescan_slot(dev);
+	}
+	kfree(dev);
+}
+
+static void pci_rescan_buses(const struct list_head *list)
+{
+	const struct list_head *l;
+	list_for_each(l,list) {
+		const struct pci_bus *b = pci_bus_b(l);
+		pci_rescan_bus(b);
+		pci_rescan_buses(&b->children);
+	}
+}
+
+static void pci_rescan(void) {
+	pci_rescan_buses(&pci_root_buses);
+}
+
+
 static int enable_slot(struct hotplug_slot *hotplug_slot)
 {
+	/* mis-use enable_slot for rescanning of pci bus */
+	pci_rescan();
 	return -ENODEV;
 }
 

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

* Re: Is there a user space pci rescan method?
  2004-10-10  0:59                           ` Jan Dittmer
@ 2004-10-10 13:45                             ` Jan Dittmer
  2004-10-30  4:16                               ` Greg KH
  0 siblings, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-10-10 13:45 UTC (permalink / raw)
  To: linux-kernel; +Cc: Jan Dittmer, Greg KH, Rolf Eike Beer, Hotplug List

[-- Attachment #1: Type: text/plain, Size: 2334 bytes --]

Jan Dittmer wrote:
> Jan Dittmer wrote:
> 
>>Greg KH wrote:
>>
>>
>>>Please just add the "rescan" support to fakephp, and everyone will be
>>>happy...
>>
>>
>>Well, I started to work on this for fun. What I currently have is a
>>stand-alone module which rescans the pci bus on insert and enables
>>previously disabled devices. This works (at least with my ieee1394 port).
>>Problem is, that fakephp does not get notified about this new pci device
>>and no new file is created in /sys/bus/pci/slots. So I'm going to add
>>this rescan functionality directly to fakephp.
>>Question is: where? My current idea is a fake hotplug slot "rescan" in
>>/sys/bus/pci/slots , where you can write "1" into the "power" attribute.
>>FWIW I've attached the standalone module and a kernel patch which rips
>>out the pci_bus_add_device functionality from pci_bus_add_devices.
> 
> 
> Well, here is a quick & dirty hack, which adds this function to
> enable_slot in fakephp. So if you write "1" in the power attribute of
> any slot, the whole bus gets rescanned (you still need the
> pci_bus_add_device.patch from the previous mail).

Well one last update. This version also handles deactivation of
subfunctions correctly, ie. when the parent should be disabled, all
subfunctions will be disabled first.

Small demo:
 # modprobe fakephp
 # ls /sys/bus/pci/slots | grep "0000:04"
0000:04:02.0
0000:04:02.1
0000:04:02.2
0000:04:03.0
0000:04:03.1
 # echo -n 0 > /sys/bus/pci/slots/0000\:04\:02.0/power
 # ls /sys/bus/pci/slots | grep "0000:04"
0000:04:03.0
0000:04:03.1
 # echo -n 1 > /sys/bus/pci/slots/0000\:03\:01.0/power
 # ls /sys/bus/pci/slots | grep "0000:04"
0000:04:02.0
0000:04:02.1
0000:04:02.2
0000:04:03.0
0000:04:03.1
 #lspci | grep "0000:04"
0000:04:02.0 Multimedia audio controller: Creative Labs SB Audigy (rev 03)
0000:04:02.1 Input device controller: Creative Labs SB Audigy MIDI/Game
port (rev 03)
0000:04:02.2 FireWire (IEEE 1394): Creative Labs SB Audigy FireWire Port
0000:04:03.0 SCSI storage controller: Adaptec AHA-3960D / AIC-7899A
U160/m (rev 01)
0000:04:03.1 SCSI storage controller: Adaptec AHA-3960D / AIC-7899A
U160/m (rev 01)

Sound plays fine afterwards.
Actually this only works only once or twice. At some point the removal
command will hang (but I suppose this is a problem with either
snd-emu10k1 or ieee1394).

Jan



[-- Attachment #2: fakephp-rescan-on-enable-3.patch --]
[-- Type: text/x-patch, Size: 4273 bytes --]

diff -X /home/jdittmer/stuff/diffignore -ur linus/drivers/pci/hotplug/fakephp.c pcirescan/drivers/pci/hotplug/fakephp.c
--- linus/drivers/pci/hotplug/fakephp.c	2004-01-09 07:59:45.000000000 +0100
+++ pcirescan/drivers/pci/hotplug/fakephp.c	2004-10-10 15:15:55.000000000 +0200
@@ -165,14 +165,126 @@
 		err("Problem unregistering a slot %s\n", dslot->slot->name);
 }
 
+/**
+ * Rescan slot.
+ * Tries hard not to re-enable already existing devices
+ * also handle scanning of subfunctions
+ * 
+ * @param temp   Device template. Should be set: bus and devfn.
+ */
+static void pci_rescan_slot(struct pci_dev *temp)
+{
+	struct pci_bus *bus = temp->bus;
+	struct pci_dev* old_dev = pci_find_slot(bus->number, temp->devfn);
+	struct pci_dev *dev = NULL;
+	int func = 0;
+	int new_multi = 0;  /* new multifunction device */
+	u8 hdr_type;
+	if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
+		temp->hdr_type = hdr_type & 0x7f;
+		new_multi=hdr_type & 0x80;
+		if (!old_dev) {
+			dev = pci_scan_single_device(bus, temp->devfn);
+			if (dev) {
+				dbg("Found new device on %s function %x:%x %x\n",
+						bus->name, temp->devfn >> 3,
+						temp->devfn & 7,
+						hdr_type);
+				pci_bus_add_device(dev);
+				add_slot(dev);
+			}
+		}
+		if (new_multi) { /* continue scanning for other functions */
+			for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
+				if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
+					continue;
+				temp->hdr_type = hdr_type & 0x7f;
+
+				old_dev = pci_find_slot(bus->number, temp->devfn);
+				if (!old_dev) {
+					dev = pci_scan_single_device(bus, temp->devfn);
+					if (dev) {
+						dbg("Found new device on %s function %x:%x %x\n",
+								bus->name, temp->devfn >> 3,
+								temp->devfn & 7,
+								hdr_type);
+						pci_bus_add_device(dev);
+						add_slot(dev);
+					}
+				} 
+			}
+		}
+	}
+}
+
+
+/**
+ * Rescan PCI bus.
+ * call pci_rescan_slot for each possible function of the bus
+ * 
+ * @param bus
+ */
+static void pci_rescan_bus(const struct pci_bus *bus)
+{
+	unsigned int devfn;
+	struct pci_dev *dev;
+	dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+	if (!dev)
+		return;
+
+	memset(dev, 0, sizeof(dev));
+	dev->bus = (struct pci_bus*)bus;
+	dev->sysdata = bus->sysdata;
+	for (devfn = 0; devfn < 0x100; devfn += 8) {
+		dev->devfn = devfn;
+		pci_rescan_slot(dev);
+	}
+	kfree(dev);
+}
+
+/* recursively scan all buses */
+static void pci_rescan_buses(const struct list_head *list)
+{
+	const struct list_head *l;
+	list_for_each(l,list) {
+		const struct pci_bus *b = pci_bus_b(l);
+		pci_rescan_bus(b);
+		pci_rescan_buses(&b->children);
+	}
+}
+
+/* initiate rescan of all pci buses */
+static void pci_rescan(void) {
+	pci_rescan_buses(&pci_root_buses);
+}
+
+
 static int enable_slot(struct hotplug_slot *hotplug_slot)
 {
+	/* mis-use enable_slot for rescanning of the pci bus */
+	pci_rescan();
 	return -ENODEV;
 }
 
+/* find the hotplug_slot for the pci_dev */
+static struct hotplug_slot *get_slot_from_dev(struct pci_dev *dev) 
+{
+	struct dummy_slot *dslot;
+
+	list_for_each_entry(dslot, &slot_list, node) {
+		if (dslot->dev == dev)
+			return dslot->slot;
+	}
+	return NULL;
+}
+
+
 static int disable_slot(struct hotplug_slot *slot)
 {
 	struct dummy_slot *dslot;
+	struct hotplug_slot *hslot;
+	struct pci_dev *dev;
+	int func;
 
 	if (!slot)
 		return -ENODEV;
@@ -185,6 +297,28 @@
 		err("Can't remove PCI devices with other PCI devices behind it yet.\n");
 		return -ENODEV;
 	}
+	/* search for subfunctions and disable them first */
+	if (!(dslot->dev->devfn & 7)) {
+		dbg("Searching for subfunctions\n");
+		for (func=1;func<8;func++) {
+			dbg("Considering %x %x+%x\n", 
+					dslot->dev->bus->number,
+					dslot->dev->devfn,
+					func);
+			dev = pci_find_slot(dslot->dev->bus->number, dslot->dev->devfn + func);
+			if (dev) {
+				dbg("Slot %s Removed <%s>\n", dslot->dev->slot_name, dslot->dev->pretty_name);
+				hslot = get_slot_from_dev(dev);
+				if (hslot)
+					disable_slot(hslot);
+				else {
+					err("Hotplug slot not found for subordinate pci-device\n");
+					return -ENODEV;
+				}
+			} else 
+				dbg("No device in slot found\n");
+		}
+	}
 
 	/* remove the device from the pci core */
 	pci_remove_bus_device(dslot->dev);


[-- Attachment #3: pci_bus_add_device.patch --]
[-- Type: text/x-patch, Size: 1693 bytes --]

--- linus/include/linux/pci.h	2004-10-06 19:58:35.000000000 +0200
+++ pcirescan/include/linux/pci.h	2004-10-10 01:55:41.000000000 +0200
@@ -704,6 +704,7 @@
 int pci_scan_slot(struct pci_bus *bus, int devfn);
 struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
 unsigned int pci_scan_child_bus(struct pci_bus *bus);
+void pci_bus_add_device(struct pci_dev *dev);
 void pci_bus_add_devices(struct pci_bus *bus);
 void pci_name_device(struct pci_dev *dev);
 char *pci_class_name(u32 class);
diff -ur linus/drivers/pci/bus.c pcirescan/drivers/pci/bus.c
--- linus/drivers/pci/bus.c	2004-05-10 10:06:44.000000000 +0200
+++ pcirescan/drivers/pci/bus.c	2004-10-10 01:29:50.000000000 +0200
@@ -69,6 +69,20 @@
 }
 
 /**
+ * add a single device
+ */
+void __devinit pci_bus_add_device(struct pci_dev *dev) {
+	device_add(&dev->dev);
+
+	spin_lock(&pci_bus_lock);
+	list_add_tail(&dev->global_list, &pci_devices);
+	spin_unlock(&pci_bus_lock);
+
+	pci_proc_attach_device(dev);
+	pci_create_sysfs_dev_files(dev);
+}
+
+/**
  * pci_bus_add_devices - insert newly discovered PCI devices
  * @bus: bus to check for new devices
  *
@@ -91,16 +105,7 @@
 		 */
 		if (!list_empty(&dev->global_list))
 			continue;
-
-		device_add(&dev->dev);
-
-		spin_lock(&pci_bus_lock);
-		list_add_tail(&dev->global_list, &pci_devices);
-		spin_unlock(&pci_bus_lock);
-
-		pci_proc_attach_device(dev);
-		pci_create_sysfs_dev_files(dev);
-
+		pci_bus_add_device(dev);
 	}
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -136,5 +141,6 @@
 }
 
 EXPORT_SYMBOL(pci_bus_alloc_resource);
+EXPORT_SYMBOL(pci_bus_add_device);
 EXPORT_SYMBOL(pci_bus_add_devices);
 EXPORT_SYMBOL(pci_enable_bridges);


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

* Re: Is there a user space pci rescan method?
  2004-10-10 13:45                             ` Jan Dittmer
@ 2004-10-30  4:16                               ` Greg KH
  2004-10-31 23:59                                 ` [patch 1/2] fakephp: introduce pci_bus_add_device Jan Dittmer
  2004-10-31 23:59                                 ` [patch 2/2] fakephp: add pci bus rescan ability Jan Dittmer
  0 siblings, 2 replies; 31+ messages in thread
From: Greg KH @ 2004-10-30  4:16 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: linux-kernel, Rolf Eike Beer, Hotplug List

On Sun, Oct 10, 2004 at 03:45:29PM +0200, Jan Dittmer wrote:
> Jan Dittmer wrote:
> > Jan Dittmer wrote:
> > 
> >>Greg KH wrote:
> >>
> >>
> >>>Please just add the "rescan" support to fakephp, and everyone will be
> >>>happy...
> >>
> >>
> >>Well, I started to work on this for fun. What I currently have is a
> >>stand-alone module which rescans the pci bus on insert and enables
> >>previously disabled devices. This works (at least with my ieee1394 port).
> >>Problem is, that fakephp does not get notified about this new pci device
> >>and no new file is created in /sys/bus/pci/slots. So I'm going to add
> >>this rescan functionality directly to fakephp.
> >>Question is: where? My current idea is a fake hotplug slot "rescan" in
> >>/sys/bus/pci/slots , where you can write "1" into the "power" attribute.
> >>FWIW I've attached the standalone module and a kernel patch which rips
> >>out the pci_bus_add_device functionality from pci_bus_add_devices.
> > 
> > 
> > Well, here is a quick & dirty hack, which adds this function to
> > enable_slot in fakephp. So if you write "1" in the power attribute of
> > any slot, the whole bus gets rescanned (you still need the
> > pci_bus_add_device.patch from the previous mail).
> 
> Well one last update. This version also handles deactivation of
> subfunctions correctly, ie. when the parent should be disabled, all
> subfunctions will be disabled first.

Nice, I like it.  Care to resend this in 2 different emails, with a good
description in the subject line, and in the body of the email, and a
"Signed-off-by:" line in it too (as per the
Documentation/SubmittingPatches file) so I can apply these to the tree?

thanks,

greg k-h

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

* [patch 1/2] fakephp: introduce pci_bus_add_device
  2004-10-30  4:16                               ` Greg KH
@ 2004-10-31 23:59                                 ` Jan Dittmer
  2004-11-01  9:35                                   ` Christoph Hellwig
  2004-10-31 23:59                                 ` [patch 2/2] fakephp: add pci bus rescan ability Jan Dittmer
  1 sibling, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-10-31 23:59 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Hotplug List

fakephp needs to add newly discovered devices to the global pci list.
Therefore seperate out the appropriate chunk from pci_bus_add_devices
to pci_bus_add_device to add a single device to sysfs, procfs
and the global device list.

Signed-off-by: Jan Dittmer <jdittmer@ppp0.net>

===== drivers/pci/bus.c 1.9 vs edited =====
--- 1.9/drivers/pci/bus.c       2004-04-11 00:27:59 +02:00
+++ edited/drivers/pci/bus.c    2004-10-31 23:24:10 +01:00
@@ -69,6 +69,24 @@
 }

 /**
+ * add a single device
+ * @dev: device to add
+ *
+ * This adds a single pci device to the global
+ * device list and adds sysfs and procfs entries for it
+ */
+void __devinit pci_bus_add_device(struct pci_dev *dev) {
+       device_add(&dev->dev);
+
+       spin_lock(&pci_bus_lock);
+       list_add_tail(&dev->global_list, &pci_devices);
+       spin_unlock(&pci_bus_lock);
+
+       pci_proc_attach_device(dev);
+       pci_create_sysfs_dev_files(dev);
+}
+
+/**
  * pci_bus_add_devices - insert newly discovered PCI devices
  * @bus: bus to check for new devices
  *
@@ -91,16 +109,7 @@
                 */
                if (!list_empty(&dev->global_list))
                        continue;
-
-               device_add(&dev->dev);
-
-               spin_lock(&pci_bus_lock);
-               list_add_tail(&dev->global_list, &pci_devices);
-               spin_unlock(&pci_bus_lock);
-
-               pci_proc_attach_device(dev);
-               pci_create_sysfs_dev_files(dev);
-
+               pci_bus_add_device(dev);
        }

        list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -136,5 +145,6 @@
 }

 EXPORT_SYMBOL(pci_bus_alloc_resource);
+EXPORT_SYMBOL(pci_bus_add_device);
 EXPORT_SYMBOL(pci_bus_add_devices);
 EXPORT_SYMBOL(pci_enable_bridges);
===== include/linux/pci.h 1.139 vs edited =====
--- 1.139/include/linux/pci.h   2004-10-06 00:56:26 +02:00
+++ edited/include/linux/pci.h  2004-10-31 23:10:04 +01:00
@@ -713,6 +713,7 @@
 int pci_scan_slot(struct pci_bus *bus, int devfn);
 struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
 unsigned int pci_scan_child_bus(struct pci_bus *bus);
+void pci_bus_add_device(struct pci_dev *dev);
 void pci_bus_add_devices(struct pci_bus *bus);
 void pci_name_device(struct pci_dev *dev);
 char *pci_class_name(u32 class);


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

* [patch 2/2] fakephp: add pci bus rescan ability
  2004-10-30  4:16                               ` Greg KH
  2004-10-31 23:59                                 ` [patch 1/2] fakephp: introduce pci_bus_add_device Jan Dittmer
@ 2004-10-31 23:59                                 ` Jan Dittmer
  2004-11-12 18:59                                   ` Greg KH
  1 sibling, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-10-31 23:59 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Hotplug List

This adds the ability to rescan the pci bus for newly inserted,
reprogrammed or previously disabled pci devices.
To initiate a rescan you need to write '1' to any of the
/sys/bus/pci/slots/*/power control files. No known pci devices
will be touched.
Additionally this fixes a bug, when someone tries to disable
a device with subfunctions. The subfunctions will be disabled first now.

Short demo:
 # modprobe fakephp
 # ls /sys/bus/pci/slots | grep "0000:04"
0000:04:02.0
0000:04:02.1
0000:04:02.2
0000:04:03.0
0000:04:03.1
 # echo -n 0 > /sys/bus/pci/slots/0000\:04\:02.0/power
 # ls /sys/bus/pci/slots | grep "0000:04"
0000:04:03.0
0000:04:03.1
 # echo -n 1 > /sys/bus/pci/slots/0000\:03\:01.0/power
 # ls /sys/bus/pci/slots | grep "0000:04"
0000:04:02.0
0000:04:02.1
0000:04:02.2
0000:04:03.0
0000:04:03.1
 # lspci | grep "0000:04"
0000:04:02.0 Multimedia audio controller: Creative Labs SB Audigy (rev 03)
0000:04:02.1 Input device controller: Creative Labs SB Audigy MIDI/Gameport (rev 03)
0000:04:02.2 FireWire (IEEE 1394): Creative Labs SB Audigy FireWire Port
0000:04:03.0 SCSI storage controller: Adaptec AHA-3960D / AIC-7899A U160/m (rev 01)
0000:04:03.1 SCSI storage controller: Adaptec AHA-3960D / AIC-7899A U160/m (rev 01)

Signed-off-by: Jan Dittmer <jdittmer@ppp0.net>

===== drivers/pci/hotplug/fakephp.c 1.2 vs edited =====
--- 1.2/drivers/pci/hotplug/fakephp.c	2003-08-27 16:44:50 +02:00
+++ edited/drivers/pci/hotplug/fakephp.c	2004-11-01 00:15:26 +01:00
@@ -165,14 +165,123 @@
 		err("Problem unregistering a slot %s\n", dslot->slot->name);
 }

+/**
+ * Rescan slot.
+ * Tries hard not to re-enable already existing devices
+ * also handles scanning of subfunctions
+ *
+ * @param temp   Device template. Should be set: bus and devfn.
+ */
+static void pci_rescan_slot(struct pci_dev *temp)
+{
+	struct pci_bus *bus = temp->bus;
+	struct pci_dev *dev;
+	int func;
+	u8 hdr_type;
+	if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
+		temp->hdr_type = hdr_type & 0x7f;
+		if (!pci_find_slot(bus->number, temp->devfn)) {
+			dev = pci_scan_single_device(bus, temp->devfn);
+			if (dev) {
+				dbg("New device on %s function %x:%x\n",
+					bus->name, temp->devfn >> 3,
+					temp->devfn & 7);
+				pci_bus_add_device(dev);
+				add_slot(dev);
+			}
+		}
+		/* multifunction device? */
+		if (!(hdr_type & 0x80))
+			return;
+
+		/* continue scanning for other functions */
+		for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
+			if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
+				continue;
+			temp->hdr_type = hdr_type & 0x7f;
+
+			if (!pci_find_slot(bus->number, temp->devfn)) {
+				dev = pci_scan_single_device(bus, temp->devfn);
+				if (dev) {
+					dbg("New device on %s function %x:%x\n",
+						bus->name, temp->devfn >> 3,
+						temp->devfn & 7);
+					pci_bus_add_device(dev);
+					add_slot(dev);
+				}
+			}
+		}
+	}
+}
+
+
+/**
+ * Rescan PCI bus.
+ * call pci_rescan_slot for each possible function of the bus
+ *
+ * @param bus
+ */
+static void pci_rescan_bus(const struct pci_bus *bus)
+{
+	unsigned int devfn;
+	struct pci_dev *dev;
+	dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+	if (!dev)
+		return;
+
+	memset(dev, 0, sizeof(dev));
+	dev->bus = (struct pci_bus*)bus;
+	dev->sysdata = bus->sysdata;
+	for (devfn = 0; devfn < 0x100; devfn += 8) {
+		dev->devfn = devfn;
+		pci_rescan_slot(dev);
+	}
+	kfree(dev);
+}
+
+/* recursively scan all buses */
+static void pci_rescan_buses(const struct list_head *list)
+{
+	const struct list_head *l;
+	list_for_each(l,list) {
+		const struct pci_bus *b = pci_bus_b(l);
+		pci_rescan_bus(b);
+		pci_rescan_buses(&b->children);
+	}
+}
+
+/* initiate rescan of all pci buses */
+static inline void pci_rescan(void) {
+	pci_rescan_buses(&pci_root_buses);
+}
+
+
 static int enable_slot(struct hotplug_slot *hotplug_slot)
 {
+	/* mis-use enable_slot for rescanning of the pci bus */
+	pci_rescan();
 	return -ENODEV;
 }

+/* find the hotplug_slot for the pci_dev */
+static struct hotplug_slot *get_slot_from_dev(struct pci_dev *dev)
+{
+	struct dummy_slot *dslot;
+
+	list_for_each_entry(dslot, &slot_list, node) {
+		if (dslot->dev == dev)
+			return dslot->slot;
+	}
+	return NULL;
+}
+
+
 static int disable_slot(struct hotplug_slot *slot)
 {
 	struct dummy_slot *dslot;
+	struct hotplug_slot *hslot;
+	struct pci_dev *dev;
+	int func;

 	if (!slot)
 		return -ENODEV;
@@ -185,6 +294,23 @@
 		err("Can't remove PCI devices with other PCI devices behind it yet.\n");
 		return -ENODEV;
 	}
+	/* search for subfunctions and disable them first */
+	if (!(dslot->dev->devfn & 7)) {
+		for (func = 1; func < 8; func++) {
+			dev = pci_find_slot(dslot->dev->bus->number,
+					dslot->dev->devfn + func);
+			if (dev) {
+				hslot = get_slot_from_dev(dev);
+				if (hslot)
+					disable_slot(hslot);
+				else {
+					err("Hotplug slot not found for subfunction of PCI device\n");
+					return -ENODEV;
+				}
+			} else
+				dbg("No device in slot found\n");
+		}
+	}

 	/* remove the device from the pci core */
 	pci_remove_bus_device(dslot->dev);
@@ -227,6 +353,6 @@
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
+module_param(debug, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debugging mode enabled or not");



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

* Re: [patch 1/2] fakephp: introduce pci_bus_add_device
  2004-10-31 23:59                                 ` [patch 1/2] fakephp: introduce pci_bus_add_device Jan Dittmer
@ 2004-11-01  9:35                                   ` Christoph Hellwig
  2004-11-02 22:51                                     ` Jan Dittmer
  0 siblings, 1 reply; 31+ messages in thread
From: Christoph Hellwig @ 2004-11-01  9:35 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: Greg KH, linux-kernel, Hotplug List

On Mon, Nov 01, 2004 at 12:59:54AM +0100, Jan Dittmer wrote:
> fakephp needs to add newly discovered devices to the global pci list.
> Therefore seperate out the appropriate chunk from pci_bus_add_devices
> to pci_bus_add_device to add a single device to sysfs, procfs
> and the global device list.
> 
> Signed-off-by: Jan Dittmer <jdittmer@ppp0.net>
> 
> ===== drivers/pci/bus.c 1.9 vs edited =====
> --- 1.9/drivers/pci/bus.c       2004-04-11 00:27:59 +02:00
> +++ edited/drivers/pci/bus.c    2004-10-31 23:24:10 +01:00
> @@ -69,6 +69,24 @@
>  }
> 
>  /**
> + * add a single device
> + * @dev: device to add
> + *
> + * This adds a single pci device to the global
> + * device list and adds sysfs and procfs entries for it
> + */
> +void __devinit pci_bus_add_device(struct pci_dev *dev) {

the brace should go to a line of it's own


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

* Re: [patch 1/2] fakephp: introduce pci_bus_add_device
  2004-11-01  9:35                                   ` Christoph Hellwig
@ 2004-11-02 22:51                                     ` Jan Dittmer
  2004-11-11 23:47                                       ` Greg KH
  0 siblings, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-11-02 22:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Greg KH, linux-kernel, Hotplug List

Christoph Hellwig wrote:
> On Mon, Nov 01, 2004 at 12:59:54AM +0100, Jan Dittmer wrote:
> 
>>fakephp needs to add newly discovered devices to the global pci list.
>>Therefore seperate out the appropriate chunk from pci_bus_add_devices
>>to pci_bus_add_device to add a single device to sysfs, procfs
>>and the global device list.
>>
>>Signed-off-by: Jan Dittmer <jdittmer@ppp0.net>

> the brace should go to a line of it's own

Sorry about that, updated patch follows:

--- 1.9/drivers/pci/bus.c       2004-04-11 00:27:59 +02:00
+++ edited/drivers/pci/bus.c    2004-11-01 10:41:27 +01:00
@@ -69,6 +69,25 @@
 }

 /**
+ * add a single device
+ * @dev: device to add
+ *
+ * This adds a single pci device to the global
+ * device list and adds sysfs and procfs entries
+ */
+void __devinit pci_bus_add_device(struct pci_dev *dev)
+{
+       device_add(&dev->dev);
+
+       spin_lock(&pci_bus_lock);
+       list_add_tail(&dev->global_list, &pci_devices);
+       spin_unlock(&pci_bus_lock);
+
+       pci_proc_attach_device(dev);
+       pci_create_sysfs_dev_files(dev);
+}
+
+/**
  * pci_bus_add_devices - insert newly discovered PCI devices
  * @bus: bus to check for new devices
  *
@@ -91,16 +110,7 @@
                 */
                if (!list_empty(&dev->global_list))
                        continue;
-
-               device_add(&dev->dev);
-
-               spin_lock(&pci_bus_lock);
-               list_add_tail(&dev->global_list, &pci_devices);
-               spin_unlock(&pci_bus_lock);
-
-               pci_proc_attach_device(dev);
-               pci_create_sysfs_dev_files(dev);
-
+               pci_bus_add_device(dev);
        }

        list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -136,5 +146,6 @@
 }

 EXPORT_SYMBOL(pci_bus_alloc_resource);
+EXPORT_SYMBOL(pci_bus_add_device);
 EXPORT_SYMBOL(pci_bus_add_devices);
 EXPORT_SYMBOL(pci_enable_bridges);
--- 1.139/include/linux/pci.h   2004-10-06 00:56:26 +02:00
+++ edited/include/linux/pci.h  2004-10-31 23:10:04 +01:00
@@ -713,6 +713,7 @@
 int pci_scan_slot(struct pci_bus *bus, int devfn);
 struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
 unsigned int pci_scan_child_bus(struct pci_bus *bus);
+void pci_bus_add_device(struct pci_dev *dev);
 void pci_bus_add_devices(struct pci_bus *bus);
 void pci_name_device(struct pci_dev *dev);
 char *pci_class_name(u32 class);



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

* Re: [patch 1/2] fakephp: introduce pci_bus_add_device
  2004-11-02 22:51                                     ` Jan Dittmer
@ 2004-11-11 23:47                                       ` Greg KH
  2004-11-12  0:13                                         ` Jan Dittmer
  0 siblings, 1 reply; 31+ messages in thread
From: Greg KH @ 2004-11-11 23:47 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: Christoph Hellwig, linux-kernel, Hotplug List

On Tue, Nov 02, 2004 at 11:51:15PM +0100, Jan Dittmer wrote:
> Christoph Hellwig wrote:
> > On Mon, Nov 01, 2004 at 12:59:54AM +0100, Jan Dittmer wrote:
> > 
> >>fakephp needs to add newly discovered devices to the global pci list.
> >>Therefore seperate out the appropriate chunk from pci_bus_add_devices
> >>to pci_bus_add_device to add a single device to sysfs, procfs
> >>and the global device list.
> >>
> >>Signed-off-by: Jan Dittmer <jdittmer@ppp0.net>
> 
> > the brace should go to a line of it's own
> 
> Sorry about that, updated patch follows:

Ugh, your email client ate all of the tabs and spit them out as spaces
for this patch :(

Care to try it again?

thanks,

greg k-h

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

* Re: [patch 1/2] fakephp: introduce pci_bus_add_device
  2004-11-11 23:47                                       ` Greg KH
@ 2004-11-12  0:13                                         ` Jan Dittmer
  2004-11-12 18:59                                           ` Greg KH
  0 siblings, 1 reply; 31+ messages in thread
From: Jan Dittmer @ 2004-11-12  0:13 UTC (permalink / raw)
  To: Greg KH; +Cc: Christoph Hellwig, linux-kernel, Hotplug List

[-- Attachment #1: Type: text/plain, Size: 818 bytes --]

Greg KH wrote:
> On Tue, Nov 02, 2004 at 11:51:15PM +0100, Jan Dittmer wrote:
> 
>>Christoph Hellwig wrote:
>>
>>>On Mon, Nov 01, 2004 at 12:59:54AM +0100, Jan Dittmer wrote:
>>>
>>>
>>>>fakephp needs to add newly discovered devices to the global pci list.
>>>>Therefore seperate out the appropriate chunk from pci_bus_add_devices
>>>>to pci_bus_add_device to add a single device to sysfs, procfs
>>>>and the global device list.
>>>>
>>>>Signed-off-by: Jan Dittmer <jdittmer@ppp0.net>
>>
>>>the brace should go to a line of it's own
>>
>>Sorry about that, updated patch follows:
> 
> 
> Ugh, your email client ate all of the tabs and spit them out as spaces
> for this patch :(
> 
> Care to try it again?

Well, I still don't know how to do this with Thunderbird as
non attachment. So here it goes as attachment.

Jan

[-- Attachment #2: pci_bus_add_device-2.patch --]
[-- Type: text/x-patch, Size: 1806 bytes --]

===== drivers/pci/bus.c 1.9 vs edited =====
--- 1.9/drivers/pci/bus.c	2004-04-11 00:27:59 +02:00
+++ edited/drivers/pci/bus.c	2004-11-01 10:41:27 +01:00
@@ -69,6 +69,25 @@
 }
 
 /**
+ * add a single device
+ * @dev: device to add
+ *
+ * This adds a single pci device to the global
+ * device list and adds sysfs and procfs entries
+ */
+void __devinit pci_bus_add_device(struct pci_dev *dev)
+{
+	device_add(&dev->dev);
+
+	spin_lock(&pci_bus_lock);
+	list_add_tail(&dev->global_list, &pci_devices);
+	spin_unlock(&pci_bus_lock);
+
+	pci_proc_attach_device(dev);
+	pci_create_sysfs_dev_files(dev);
+}
+
+/**
  * pci_bus_add_devices - insert newly discovered PCI devices
  * @bus: bus to check for new devices
  *
@@ -91,16 +110,7 @@
 		 */
 		if (!list_empty(&dev->global_list))
 			continue;
-
-		device_add(&dev->dev);
-
-		spin_lock(&pci_bus_lock);
-		list_add_tail(&dev->global_list, &pci_devices);
-		spin_unlock(&pci_bus_lock);
-
-		pci_proc_attach_device(dev);
-		pci_create_sysfs_dev_files(dev);
-
+		pci_bus_add_device(dev);
 	}
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -136,5 +146,6 @@
 }
 
 EXPORT_SYMBOL(pci_bus_alloc_resource);
+EXPORT_SYMBOL(pci_bus_add_device);
 EXPORT_SYMBOL(pci_bus_add_devices);
 EXPORT_SYMBOL(pci_enable_bridges);
===== include/linux/pci.h 1.139 vs edited =====
--- 1.139/include/linux/pci.h	2004-10-06 00:56:26 +02:00
+++ edited/include/linux/pci.h	2004-10-31 23:10:04 +01:00
@@ -713,6 +713,7 @@
 int pci_scan_slot(struct pci_bus *bus, int devfn);
 struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
 unsigned int pci_scan_child_bus(struct pci_bus *bus);
+void pci_bus_add_device(struct pci_dev *dev);
 void pci_bus_add_devices(struct pci_bus *bus);
 void pci_name_device(struct pci_dev *dev);
 char *pci_class_name(u32 class);

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

* Re: [patch 2/2] fakephp: add pci bus rescan ability
  2004-10-31 23:59                                 ` [patch 2/2] fakephp: add pci bus rescan ability Jan Dittmer
@ 2004-11-12 18:59                                   ` Greg KH
  0 siblings, 0 replies; 31+ messages in thread
From: Greg KH @ 2004-11-12 18:59 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: linux-kernel, Hotplug List

On Mon, Nov 01, 2004 at 12:59:55AM +0100, Jan Dittmer wrote:
> This adds the ability to rescan the pci bus for newly inserted,
> reprogrammed or previously disabled pci devices.
> To initiate a rescan you need to write '1' to any of the
> /sys/bus/pci/slots/*/power control files. No known pci devices
> will be touched.
> Additionally this fixes a bug, when someone tries to disable
> a device with subfunctions. The subfunctions will be disabled first now.

Very nice, thanks for doing this work.

Applied, thanks.

greg k-h

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

* Re: [patch 1/2] fakephp: introduce pci_bus_add_device
  2004-11-12  0:13                                         ` Jan Dittmer
@ 2004-11-12 18:59                                           ` Greg KH
  0 siblings, 0 replies; 31+ messages in thread
From: Greg KH @ 2004-11-12 18:59 UTC (permalink / raw)
  To: Jan Dittmer; +Cc: Christoph Hellwig, linux-kernel, Hotplug List

On Fri, Nov 12, 2004 at 01:13:13AM +0100, Jan Dittmer wrote:
> Greg KH wrote:
> > On Tue, Nov 02, 2004 at 11:51:15PM +0100, Jan Dittmer wrote:
> > 
> >>Christoph Hellwig wrote:
> >>
> >>>On Mon, Nov 01, 2004 at 12:59:54AM +0100, Jan Dittmer wrote:
> >>>
> >>>
> >>>>fakephp needs to add newly discovered devices to the global pci list.
> >>>>Therefore seperate out the appropriate chunk from pci_bus_add_devices
> >>>>to pci_bus_add_device to add a single device to sysfs, procfs
> >>>>and the global device list.
> >>>>
> >>>>Signed-off-by: Jan Dittmer <jdittmer@ppp0.net>
> >>
> >>>the brace should go to a line of it's own
> >>
> >>Sorry about that, updated patch follows:
> > 
> > 
> > Ugh, your email client ate all of the tabs and spit them out as spaces
> > for this patch :(
> > 
> > Care to try it again?
> 
> Well, I still don't know how to do this with Thunderbird as
> non attachment. So here it goes as attachment.

I'll live with that :)

Applied, thanks,

greg k-h

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

end of thread, other threads:[~2004-11-12 19:16 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-09-22 22:00 Is there a user space pci rescan method? Dave Aubin
2004-09-22 23:58 ` Jan Dittmer
2004-09-23  0:26   ` Greg KH
2004-09-23 15:04     ` Jan Dittmer
2004-09-23 16:49       ` Rolf Eike Beer
2004-09-23 16:53         ` Jan Dittmer
2004-09-23 17:05           ` Rolf Eike Beer
2004-09-24 10:41             ` Rolf Eike Beer
2004-09-24 11:42               ` Jan Dittmer
2004-09-24 12:12                 ` Rolf Eike Beer
2004-09-24 12:16                   ` Jan Dittmer
2004-09-24 12:32                     ` Rolf Eike Beer
2004-09-24 14:55                       ` Greg KH
2004-09-27  9:14                         ` Rolf Eike Beer
2004-10-10  0:13                         ` Jan Dittmer
2004-10-10  0:59                           ` Jan Dittmer
2004-10-10 13:45                             ` Jan Dittmer
2004-10-30  4:16                               ` Greg KH
2004-10-31 23:59                                 ` [patch 1/2] fakephp: introduce pci_bus_add_device Jan Dittmer
2004-11-01  9:35                                   ` Christoph Hellwig
2004-11-02 22:51                                     ` Jan Dittmer
2004-11-11 23:47                                       ` Greg KH
2004-11-12  0:13                                         ` Jan Dittmer
2004-11-12 18:59                                           ` Greg KH
2004-10-31 23:59                                 ` [patch 2/2] fakephp: add pci bus rescan ability Jan Dittmer
2004-11-12 18:59                                   ` Greg KH
2004-09-24 13:09                     ` [Pcihpd-discuss] Re: Is there a user space pci rescan method? Matthew Wilcox
2004-09-24 13:18                       ` Rolf Eike Beer
2004-09-24 12:40               ` Jan Dittmer
2004-09-24 12:59                 ` Rolf Eike Beer
2004-09-23 23:31       ` 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).