Messing around with linux PCI hotplug

Jan 25, 2012

Been playing around with PCI hotplug on linux (3.2.1 kernel from kernel.org), or rather, with the fakephp driver (fake PCI hot plug driver). The way it works is you load the fakephp driver, and this creates a bunch of directories in /sys/bus/pci/, one per PCI device (ok, per domain/bus/device/function ) and inside each directory is a “power” file. If you write 0 to the power file, that device is “hot unplugged”. Well, not really, but the driver entry points get called as if it were hot unplugged. It’s surprisingly difficult to find the documenation for this as most searches related to linux and pci hotplug return old stuff.

You can “re-hot-plug” the device back in by echoing a 1 into /sys/bus/pci/rescan.

Anyway, here’s an example of using the fakephp driver to simulate hot unpl

root@hermes:/sys/bus/pci# uname -r
3.2.1
root@hermes:/sys/bus/pci# pwd
/sys/bus/pci
root@hermes:/sys/bus/pci# ls
devices  drivers  drivers_autoprobe  drivers_probe  rescan  resource_alignment  slots  uevent
root@hermes:/sys/bus/pci# ls slots
root@hermes:/sys/bus/pci# modprobe fakephp
root@hermes:/sys/bus/pci# ls slots
0000:00:00.0  0000:00:1b.0  0000:00:1d.2  0000:00:1e.0  0000:01:03.0  0000:01:03.3  0000:01:05.0
0000:00:02.0  0000:00:1d.0  0000:00:1d.3  0000:00:1f.0  0000:01:03.1  0000:01:03.4
0000:00:02.1  0000:00:1d.1  0000:00:1d.7  0000:00:1f.1  0000:01:03.2  0000:01:04.0

Above you see after loading the fakephp driver, the /sys/bus/pci/slots directory
is populated with device directories.

Now I go poking around looking for a network device (because I know the wired
network on my laptop isn’t currently plugged in, so if this doesn’t work, no
harm done so long as it doesn’t crash.)

root@hermes:/sys/bus/pci# lspci | grep -i net
01:04.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10)
01:05.0 Network controller: Intel Corporation PRO/Wireless 2200BG [Calexico2] Network Connection (rev 05)

So I see I have my Ethernet controller at 01:04.0. Now I start tailing
/var/log/messages so I can see the kernel’s response to my various pokings,
and I kick the unused ethernet adapter out of the system:

root@hermes:/sys/bus/pci# tail -n 0 -f /var/log/messages &
[1] 4294
root@hermes:/sys/bus/pci# echo 0 > slots/0000\:01\:04.0/power 
root@hermes:/sys/bus/pci# Jan 25 21:28:05 hermes kernel: [13781.192061] 8139too 0000:01:04.0: PCI INT A disabled

root@hermes:/sys/bus/pci# lspci | grep -i net
01:05.0 Network controller: Intel Corporation PRO/Wireless 2200BG [Calexico2] Network Connection (rev 05)

Yep, it’s gone. Now add it back in:

root@hermes:/sys/bus/pci# echo 1 > rescan
root@hermes:/sys/bus/pci# Jan 25 21:28:23 hermes kernel: [13799.587819] i915 0000:00:02.0: BAR 6: [??? 0x00000000 flags 0x2] has bogus alignment
Jan 25 21:28:23 hermes kernel: [13799.587841] pci 0000:01:04.0: BAR 0: assigned [io  0xd000-0xd0ff]
Jan 25 21:28:23 hermes kernel: [13799.587855] pci 0000:01:04.0: BAR 0: set to [io  0xd000-0xd0ff] (PCI address [0xd000-0xd0ff])
Jan 25 21:28:23 hermes kernel: [13799.587865] pci 0000:01:04.0: BAR 1: assigned [mem 0xfe801000-0xfe8010ff]
Jan 25 21:28:23 hermes kernel: [13799.587878] pci 0000:01:04.0: BAR 1: set to [mem 0xfe801000-0xfe8010ff] (PCI address [0xfe801000-0xfe8010ff])
Jan 25 21:28:23 hermes kernel: [13799.587888] yenta_cardbus 0000:01:03.0: CardBus bridge to [bus 02-01]
Jan 25 21:28:23 hermes kernel: [13799.587896] yenta_cardbus 0000:01:03.0:   bridge window [io  0x0001-0x0000]
Jan 25 21:28:23 hermes kernel: [13799.587907] yenta_cardbus 0000:01:03.0:   bridge window [io  0x0001-0x0000]
Jan 25 21:28:23 hermes kernel: [13799.587919] yenta_cardbus 0000:01:03.0:   bridge window [mem 0x00000001-0x00000000 pref]
Jan 25 21:28:23 hermes kernel: [13799.587930] yenta_cardbus 0000:01:03.0:   bridge window [mem 0x00000001-0x00000000]
Jan 25 21:28:23 hermes kernel: [13799.594036] 8139cp 0000:01:04.0: This (id 10ec:8139 rev 10) is not an 8139C+ compatible chip, use 8139too
Jan 25 21:28:23 hermes kernel: [13799.594093] 8139too 0000:01:04.0: PCI INT A -> GSI 20 (level, low) -> IRQ 20
Jan 25 21:28:23 hermes kernel: [13799.599565] 8139too 0000:01:04.0: eth0: RealTek RTL8139 at 0xd000, 00:11:d8:23:c2:86, IRQ 20
Jan 25 21:28:24 hermes kernel: [13799.639799] 8139too 0000:01:04.0: eth0: link down
Jan 25 21:28:24 hermes kernel: [13799.644372] ADDRCONF(NETDEV_UP): eth0: link is not ready

root@hermes:/sys/bus/pci# lspci | grep -i net
01:04.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10)
01:05.0 Network controller: Intel Corporation PRO/Wireless 2200BG [Calexico2] Network Connection (rev 05)
root@hermes:/sys/bus/pci#

And now it’s back.

~ by scaryreasoner on January 26, 2012.

3 Responses to “Messing around with linux PCI hotplug”

  1. Good demonstration of fakephp.

  2. Thanks!
    Un-/re-docking my tablet now works like a charm; wired ethernet interface (on the dock) is now:
    – gracefully shut down before undocking (with ‘ifconfig eth0 down; rmmod r8169; echo 1 > /sys/bus/pci/devices/…/remove’)
    – successfully brought back to life after redocking (with ‘echo 1 > /sys/bus/pci/rescan’)
    You made my day!
    (on Xubuntu 12.10, kernel 3.5.0; network-manager automatically adapts to the device status, switching to wireless adapter when appropriate)

  3. Hi,

    I’m now messing with the same problem on CenOS.
    The ‘echo 0 > power’ and ‘echo 1 > rescan’ works like a charm,…but only once o_O
    Thus, I’m able to make only one cycle of disconnect-connect the device, the second time ‘echo 0 > power’ doesn’t work. Have you faced such behavior, may be?

    Thanks in advance,
    Sergey

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: