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;
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;
/* 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
* 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
/* 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;
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;
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)