ia64/xen-unstable
changeset 10997:9e061d0dc394
[PCI] back: New virtual pci backend: slot
This backend use a slot per pci device. Contrary to vpci two functions from
one slot appear as two slots. This is useful on ia64 because it doesn't scan
functions > 0 if function 0 does not exist.
Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
This backend use a slot per pci device. Contrary to vpci two functions from
one slot appear as two slots. This is useful on ia64 because it doesn't scan
functions > 0 if function 0 does not exist.
Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Tue Aug 08 10:17:42 2006 +0100 (2006-08-08) |
parents | 51c227428166 |
children | ae14b5b77938 |
files | buildconfigs/linux-defconfig_xen0_ia64 buildconfigs/linux-defconfig_xen0_x86_32 buildconfigs/linux-defconfig_xen0_x86_64 buildconfigs/linux-defconfig_xen_ia64 buildconfigs/linux-defconfig_xen_x86_32 buildconfigs/linux-defconfig_xen_x86_64 linux-2.6-xen-sparse/drivers/xen/Kconfig linux-2.6-xen-sparse/drivers/xen/pciback/Makefile linux-2.6-xen-sparse/drivers/xen/pciback/slot.c |
line diff
1.1 --- a/buildconfigs/linux-defconfig_xen0_ia64 Tue Aug 08 10:03:30 2006 +0100 1.2 +++ b/buildconfigs/linux-defconfig_xen0_ia64 Tue Aug 08 10:17:42 2006 +0100 1.3 @@ -1533,8 +1533,9 @@ CONFIG_XEN_BLKDEV_BACKEND=y 1.4 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set 1.5 CONFIG_XEN_NETDEV_LOOPBACK=y 1.6 CONFIG_XEN_PCIDEV_BACKEND=y 1.7 -CONFIG_XEN_PCIDEV_BACKEND_VPCI=y 1.8 +# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set 1.9 # CONFIG_XEN_PCIDEV_BACKEND_PASS is not set 1.10 +CONFIG_XEN_PCIDEV_BACKEND_SLOT=y 1.11 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set 1.12 # CONFIG_XEN_TPMDEV_BACKEND is not set 1.13 CONFIG_XEN_BLKDEV_FRONTEND=y
2.1 --- a/buildconfigs/linux-defconfig_xen0_x86_32 Tue Aug 08 10:03:30 2006 +0100 2.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_32 Tue Aug 08 10:17:42 2006 +0100 2.3 @@ -1320,6 +1320,7 @@ CONFIG_XEN_BACKEND=y 2.4 CONFIG_XEN_PCIDEV_BACKEND=y 2.5 # CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set 2.6 CONFIG_XEN_PCIDEV_BACKEND_PASS=y 2.7 +# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set 2.8 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set 2.9 CONFIG_XEN_BLKDEV_BACKEND=y 2.10 CONFIG_XEN_BLKDEV_TAP=y
3.1 --- a/buildconfigs/linux-defconfig_xen0_x86_64 Tue Aug 08 10:03:30 2006 +0100 3.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_64 Tue Aug 08 10:17:42 2006 +0100 3.3 @@ -1261,6 +1261,7 @@ CONFIG_XEN_BACKEND=y 3.4 CONFIG_XEN_PCIDEV_BACKEND=y 3.5 # CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set 3.6 CONFIG_XEN_PCIDEV_BACKEND_PASS=y 3.7 +# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set 3.8 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set 3.9 CONFIG_XEN_BLKDEV_BACKEND=y 3.10 CONFIG_XEN_BLKDEV_TAP=y
4.1 --- a/buildconfigs/linux-defconfig_xen_ia64 Tue Aug 08 10:03:30 2006 +0100 4.2 +++ b/buildconfigs/linux-defconfig_xen_ia64 Tue Aug 08 10:17:42 2006 +0100 4.3 @@ -1539,8 +1539,9 @@ CONFIG_XEN_BLKDEV_BACKEND=y 4.4 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set 4.5 CONFIG_XEN_NETDEV_LOOPBACK=y 4.6 CONFIG_XEN_PCIDEV_BACKEND=y 4.7 -CONFIG_XEN_PCIDEV_BACKEND_VPCI=y 4.8 +# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set 4.9 # CONFIG_XEN_PCIDEV_BACKEND_PASS is not set 4.10 +CONFIG_XEN_PCIDEV_BACKEND_SLOT=y 4.11 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set 4.12 # CONFIG_XEN_TPMDEV_BACKEND is not set 4.13 CONFIG_XEN_BLKDEV_FRONTEND=y
5.1 --- a/buildconfigs/linux-defconfig_xen_x86_32 Tue Aug 08 10:03:30 2006 +0100 5.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32 Tue Aug 08 10:17:42 2006 +0100 5.3 @@ -3021,6 +3021,7 @@ CONFIG_XEN_BACKEND=y 5.4 CONFIG_XEN_PCIDEV_BACKEND=m 5.5 CONFIG_XEN_PCIDEV_BACKEND_VPCI=y 5.6 # CONFIG_XEN_PCIDEV_BACKEND_PASS is not set 5.7 +# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set 5.8 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set 5.9 CONFIG_XEN_BLKDEV_BACKEND=y 5.10 CONFIG_XEN_BLKDEV_TAP=y
6.1 --- a/buildconfigs/linux-defconfig_xen_x86_64 Tue Aug 08 10:03:30 2006 +0100 6.2 +++ b/buildconfigs/linux-defconfig_xen_x86_64 Tue Aug 08 10:17:42 2006 +0100 6.3 @@ -2853,6 +2853,7 @@ CONFIG_XEN_BACKEND=y 6.4 CONFIG_XEN_PCIDEV_BACKEND=m 6.5 # CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set 6.6 CONFIG_XEN_PCIDEV_BACKEND_PASS=y 6.7 +# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set 6.8 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set 6.9 CONFIG_XEN_BLKDEV_BACKEND=y 6.10 CONFIG_XEN_BLKDEV_TAP=y
7.1 --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig Tue Aug 08 10:03:30 2006 +0100 7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig Tue Aug 08 10:17:42 2006 +0100 7.3 @@ -117,7 +117,7 @@ config XEN_PCIDEV_BACKEND_VPCI 7.4 This PCI Backend hides the true PCI topology and makes the frontend 7.5 think there is a single PCI bus with only the exported devices on it. 7.6 For example, a device at 03:05.0 will be re-assigned to 00:00.0. A 7.7 - second device at 02:1a.0 will be re-assigned to 00:01.0. 7.8 + second device at 02:1a.1 will be re-assigned to 00:01.1. 7.9 7.10 config XEN_PCIDEV_BACKEND_PASS 7.11 bool "Passthrough" 7.12 @@ -129,6 +129,15 @@ config XEN_PCIDEV_BACKEND_PASS 7.13 which depend on finding their hardward in certain bus/slot 7.14 locations. 7.15 7.16 +config XEN_PCIDEV_BACKEND_SLOT 7.17 + bool "Slot" 7.18 + ---help--- 7.19 + This PCI Backend hides the true PCI topology and makes the frontend 7.20 + think there is a single PCI bus with only the exported devices on it. 7.21 + Contrary to the virtual PCI backend, a function becomes a new slot. 7.22 + For example, a device at 03:05.2 will be re-assigned to 00:00.0. A 7.23 + second device at 02:1a.1 will be re-assigned to 00:01.0. 7.24 + 7.25 endchoice 7.26 7.27 config XEN_PCIDEV_BE_DEBUG
8.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/Makefile Tue Aug 08 10:03:30 2006 +0100 8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/Makefile Tue Aug 08 10:17:42 2006 +0100 8.3 @@ -7,6 +7,7 @@ pciback-y += conf_space.o conf_space_hea 8.4 conf_space_capability_pm.o \ 8.5 conf_space_quirks.o 8.6 pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o 8.7 +pciback-$(CONFIG_XEN_PCIDEV_BACKEND_SLOT) += slot.o 8.8 pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o 8.9 8.10 ifeq ($(CONFIG_XEN_PCIDEV_BE_DEBUG),y)
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/slot.c Tue Aug 08 10:17:42 2006 +0100 9.3 @@ -0,0 +1,151 @@ 9.4 +/* 9.5 + * PCI Backend - Provides a Virtual PCI bus (with real devices) 9.6 + * to the frontend 9.7 + * 9.8 + * Author: Ryan Wilson <hap9@epoch.ncsc.mil> (vpci.c) 9.9 + * Author: Tristan Gingold <tristan.gingold@bull.net>, from vpci.c 9.10 + */ 9.11 + 9.12 +#include <linux/list.h> 9.13 +#include <linux/slab.h> 9.14 +#include <linux/pci.h> 9.15 +#include <linux/spinlock.h> 9.16 +#include "pciback.h" 9.17 + 9.18 +/* There are at most 32 slots in a pci bus. */ 9.19 +#define PCI_SLOT_MAX 32 9.20 + 9.21 +#define PCI_BUS_NBR 2 9.22 + 9.23 +struct slot_dev_data { 9.24 + /* Access to dev_list must be protected by lock */ 9.25 + struct pci_dev *slots[PCI_BUS_NBR][PCI_SLOT_MAX]; 9.26 + spinlock_t lock; 9.27 +}; 9.28 + 9.29 +struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev, 9.30 + unsigned int domain, unsigned int bus, 9.31 + unsigned int devfn) 9.32 +{ 9.33 + struct pci_dev *dev = NULL; 9.34 + struct slot_dev_data *slot_dev = pdev->pci_dev_data; 9.35 + unsigned long flags; 9.36 + 9.37 + if (domain != 0 || PCI_FUNC(devfn) != 0) 9.38 + return NULL; 9.39 + 9.40 + if (PCI_SLOT(devfn) >= PCI_SLOT_MAX || bus >= PCI_BUS_NBR) 9.41 + return NULL; 9.42 + 9.43 + spin_lock_irqsave(&slot_dev->lock, flags); 9.44 + dev = slot_dev->slots[bus][PCI_SLOT(devfn)]; 9.45 + spin_unlock_irqrestore(&slot_dev->lock, flags); 9.46 + 9.47 + return dev; 9.48 +} 9.49 + 9.50 +int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev) 9.51 +{ 9.52 + int err = 0, slot, bus; 9.53 + struct slot_dev_data *slot_dev = pdev->pci_dev_data; 9.54 + unsigned long flags; 9.55 + 9.56 + if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) { 9.57 + err = -EFAULT; 9.58 + xenbus_dev_fatal(pdev->xdev, err, 9.59 + "Can't export bridges on the virtual PCI bus"); 9.60 + goto out; 9.61 + } 9.62 + 9.63 + spin_lock_irqsave(&slot_dev->lock, flags); 9.64 + 9.65 + /* Assign to a new slot on the virtual PCI bus */ 9.66 + for (bus = 0; bus < PCI_BUS_NBR; bus++) 9.67 + for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 9.68 + if (slot_dev->slots[bus][slot] == NULL) { 9.69 + printk(KERN_INFO 9.70 + "pciback: slot: %s: assign to virtual slot %d, bus %d\n", 9.71 + pci_name(dev), slot, bus); 9.72 + slot_dev->slots[bus][slot] = dev; 9.73 + goto unlock; 9.74 + } 9.75 + } 9.76 + 9.77 + err = -ENOMEM; 9.78 + xenbus_dev_fatal(pdev->xdev, err, 9.79 + "No more space on root virtual PCI bus"); 9.80 + 9.81 + unlock: 9.82 + spin_unlock_irqrestore(&slot_dev->lock, flags); 9.83 + out: 9.84 + return err; 9.85 +} 9.86 + 9.87 +void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev) 9.88 +{ 9.89 + int slot, bus; 9.90 + struct slot_dev_data *slot_dev = pdev->pci_dev_data; 9.91 + struct pci_dev *found_dev = NULL; 9.92 + unsigned long flags; 9.93 + 9.94 + spin_lock_irqsave(&slot_dev->lock, flags); 9.95 + 9.96 + for (bus = 0; bus < PCI_BUS_NBR; bus++) 9.97 + for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 9.98 + if (slot_dev->slots[bus][slot] == dev) { 9.99 + slot_dev->slots[bus][slot] = NULL; 9.100 + found_dev = dev; 9.101 + goto out; 9.102 + } 9.103 + } 9.104 + 9.105 + out: 9.106 + spin_unlock_irqrestore(&slot_dev->lock, flags); 9.107 + 9.108 + if (found_dev) 9.109 + pcistub_put_pci_dev(found_dev); 9.110 +} 9.111 + 9.112 +int pciback_init_devices(struct pciback_device *pdev) 9.113 +{ 9.114 + int slot, bus; 9.115 + struct slot_dev_data *slot_dev; 9.116 + 9.117 + slot_dev = kmalloc(sizeof(*slot_dev), GFP_KERNEL); 9.118 + if (!slot_dev) 9.119 + return -ENOMEM; 9.120 + 9.121 + spin_lock_init(&slot_dev->lock); 9.122 + 9.123 + for (bus = 0; bus < PCI_BUS_NBR; bus++) 9.124 + for (slot = 0; slot < PCI_SLOT_MAX; slot++) 9.125 + slot_dev->slots[bus][slot] = NULL; 9.126 + 9.127 + pdev->pci_dev_data = slot_dev; 9.128 + 9.129 + return 0; 9.130 +} 9.131 + 9.132 +int pciback_publish_pci_roots(struct pciback_device *pdev, 9.133 + publish_pci_root_cb publish_cb) 9.134 +{ 9.135 + /* The Virtual PCI bus has only one root */ 9.136 + return publish_cb(pdev, 0, 0); 9.137 +} 9.138 + 9.139 +void pciback_release_devices(struct pciback_device *pdev) 9.140 +{ 9.141 + int slot, bus; 9.142 + struct slot_dev_data *slot_dev = pdev->pci_dev_data; 9.143 + struct pci_dev *dev; 9.144 + 9.145 + for (bus = 0; bus < PCI_BUS_NBR; bus++) 9.146 + for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 9.147 + dev = slot_dev->slots[bus][slot]; 9.148 + if (dev != NULL) 9.149 + pcistub_put_pci_dev(dev); 9.150 + } 9.151 + 9.152 + kfree(slot_dev); 9.153 + pdev->pci_dev_data = NULL; 9.154 +}