]> xenbits.xen.org Git - xenclient/kernel.git/commitdiff
FLR - intermediate checkin 3 3/25 - added noflr settings to allow
authorRoss Philipson <ross.philipson@citrix.com>
Wed, 25 Mar 2009 17:54:31 +0000 (13:54 -0400)
committerRoss Philipson <ross.philipson@citrix.com>
Wed, 25 Mar 2009 17:54:31 +0000 (13:54 -0400)
device level control.

 Changes to be committed:
modified:   drivers/xen/pciback/pci_stub.c
modified:   drivers/xen/pciback/pciback.h
modified:   drivers/xen/pciback/pciback_ops.c

drivers/xen/pciback/pci_stub.c
drivers/xen/pciback/pciback.h
drivers/xen/pciback/pciback_ops.c

index 55932a4278632d4f1070e29c06d69572013fb2a1..a17f24dbcc31a61366ca97b3fe4cb0f82b9494ad 100644 (file)
 static char *pci_devs_to_hide = NULL;
 module_param_named(hide, pci_devs_to_hide, charp, S_IRUGO);
 
-static int disable_flr = 0;
-module_param_named(noflr, disable_flr, int, S_IRUGO);
-
 static char *pci_devs_use_sbr = NULL;
 module_param_named(sbr, pci_devs_use_sbr, charp, S_IRUGO);
 
 static char *pci_devs_use_d3r = NULL;
 module_param_named(d3r, pci_devs_use_d3r, charp, S_IRUGO);
 
+static char *pci_devs_no_flr = NULL;
+module_param_named(noflr, pci_devs_no_flr, charp, S_IRUGO);
+
 /* Device id list holding different device type listings
  * for hiding devices and reset logic.
  */
 #define PCIBACK_ID_TYPE_HIDE  1
 #define PCIBACK_ID_TYPE_SBR   2
 #define PCIBACK_ID_TYPE_D3R   3
+#define PCIBACK_ID_TYPE_NOFLR 4
 
 struct pcistub_device_id {
        struct list_head slot_list;
@@ -64,6 +65,8 @@ static LIST_HEAD(pcistub_devices);
 static int initialize_devices = 0;
 static LIST_HEAD(seized_devices);
 
+static int disable_all_flr = 0;
+
 static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
 {
        struct pcistub_device *psdev;
@@ -244,7 +247,7 @@ void pcistub_put_pci_dev(struct pci_dev *dev, int do_flr)
        /* For pass-through devices, do an FLR (or approximate) for the device
         * before it is put back and ready for the next domain
         */
-       if (!disable_flr && do_flr)
+       if (!disable_all_flr && do_flr)
                pciback_flr_device(dev);
                
        /* Cleanup our device
@@ -384,8 +387,11 @@ static int __devinit pcistub_init_device(struct pci_dev *dev)
      * values if SBR/D3R reset logic was requested.
         */
        pciback_classify_device(dev);
-       dev_data->use_sbr = pcistub_match(dev, PCIBACK_ID_TYPE_SBR);
-       dev_data->use_d3r = pcistub_match(dev, PCIBACK_ID_TYPE_D3R);
+       dev_data->no_flr = pcistub_match(dev, PCIBACK_ID_TYPE_NOFLR);
+       if (!dev_data->no_flr) {
+               dev_data->use_sbr = pcistub_match(dev, PCIBACK_ID_TYPE_SBR);
+               dev_data->use_d3r = pcistub_match(dev, PCIBACK_ID_TYPE_D3R);
+       }
 
        /* Store the config space here where the device is off and ready to be 
         * exported before any FLRs or other resets are done
@@ -718,7 +724,12 @@ static int pcistub_device_do_flr(int domain, int bus, int slot, int func)
        /* Do an FLR (or approximate) for the device on demand and 
         * reload config
         */
-       pciback_flr_device(dev);                
+       if (!disable_all_flr) {
+               dev_info(&dev->dev, "FLR invoked for device\n");
+               pciback_flr_device(dev);
+       }
+       else
+               dev_info(&dev->dev, "FLR disabled for all devices\n");
 
 out:
        return err;
@@ -943,20 +954,29 @@ static ssize_t pcistub_resets(struct device_driver *drv, const char *buf,
                                   size_t count)
 {
        int domain, bus, slot, func;
-       int type, err;
+       int type, err = 0;
 
-       /* string begins with reset type specifier sbr=|dr3= */
+       /* string begins with reset type specifier sbr=|dr3=|noflr= */
        if (!strncmp(buf, "sbr=", 4)) {
                type = PCIBACK_ID_TYPE_SBR;
                buf += 4;
        } else if (!strncmp(buf, "d3r=", 4)) {
                type = PCIBACK_ID_TYPE_D3R;
                buf += 4;
+       } else if (!strncmp(buf, "noflr=", 6)) {
+               type = PCIBACK_ID_TYPE_NOFLR;
+               buf += 6;
        } else {
                err = -EINVAL;
                goto out;
        }
 
+       /* check special wildcard noflr */
+       if (type == PCIBACK_ID_TYPE_NOFLR && !strncmp(buf, "*", 1)) {
+               disable_all_flr = 1;
+               goto out;
+       }
+
        err = str_to_slot(buf, &domain, &bus, &slot, &func);
        if (err)
                goto out;
@@ -1019,6 +1039,14 @@ static int __init pcistub_init(void)
        if (err)
                goto out;
 
+       if (pci_devs_no_flr && *pci_devs_no_flr && !strncmp(pci_devs_no_flr, "*", 1))
+               disable_all_flr = 1; /* check special wildcard noflr */
+       else
+               err = pciback_parse_device_params(pci_devs_no_flr, PCIBACK_ID_TYPE_NOFLR, pcistub_device_id_add);
+       if (err)
+               goto out;
+
+
        /* If we're the first PCI Device Driver to register, we're the
         * first one to get offered PCI devices as they become
         * available (and thus we can be the first to grab them)
index 7086ca6fae89652d980b8ea3390e443332ad0eea..7b75878a72f0e747f827c31625498a79eba0e80e 100644 (file)
@@ -55,6 +55,7 @@ struct pciback_dev_data {
        int permissive;
        int warned_on_write;
        u32 dev_type;
+       int no_flr;
        int exp_flr_offset;
        int af_flr_offset;
        int use_sbr;
index 07fae104bfae62f53bd5f35a5f1be1d0e556346e..15b0e0a0c5ba358fb86ae20eee421dd138088ea5 100644 (file)
@@ -277,6 +277,11 @@ void pciback_flr_device(struct pci_dev *dev)
        struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
        int err = 0;
 
+       if (dev_data->no_flr) {
+               dev_dbg(&dev->dev, "FLR disabled for device\n");
+               return;
+       }
+
        do {
                /* First, always try to do an FLR */
                if (dev_data->dev_type == PCIBACK_TYPE_PCIe_ENDPOINT &&