summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/iov.c41
-rw-r--r--drivers/pci/probe.c2
-rw-r--r--drivers/pci/proc.c34
3 files changed, 53 insertions, 24 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index ee599f274f05..c93071d428f5 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -729,6 +729,47 @@ int pci_num_vf(struct pci_dev *dev)
EXPORT_SYMBOL_GPL(pci_num_vf);
/**
+ * pci_vfs_assigned - returns number of VFs are assigned to a guest
+ * @dev: the PCI device
+ *
+ * Returns number of VFs belonging to this device that are assigned to a guest.
+ * If device is not a physical function returns -ENODEV.
+ */
+int pci_vfs_assigned(struct pci_dev *dev)
+{
+ struct pci_dev *vfdev;
+ unsigned int vfs_assigned = 0;
+ unsigned short dev_id;
+
+ /* only search if we are a PF */
+ if (!dev->is_physfn)
+ return 0;
+
+ /*
+ * determine the device ID for the VFs, the vendor ID will be the
+ * same as the PF so there is no need to check for that one
+ */
+ pci_read_config_word(dev, dev->sriov->pos + PCI_SRIOV_VF_DID, &dev_id);
+
+ /* loop through all the VFs to see if we own any that are assigned */
+ vfdev = pci_get_device(dev->vendor, dev_id, NULL);
+ while (vfdev) {
+ /*
+ * It is considered assigned if it is a virtual function with
+ * our dev as the physical function and the assigned bit is set
+ */
+ if (vfdev->is_virtfn && (vfdev->physfn == dev) &&
+ (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED))
+ vfs_assigned++;
+
+ vfdev = pci_get_device(dev->vendor, dev_id, vfdev);
+ }
+
+ return vfs_assigned;
+}
+EXPORT_SYMBOL_GPL(pci_vfs_assigned);
+
+/**
* pci_sriov_set_totalvfs -- reduce the TotalVFs available
* @dev: the PCI PF device
* @numvfs: number that should be used for TotalVFs supported
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 67cd04575e2e..70f10fa3c1b2 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -990,7 +990,6 @@ int pci_setup_device(struct pci_dev *dev)
dev->sysdata = dev->bus->sysdata;
dev->dev.parent = dev->bus->bridge;
dev->dev.bus = &pci_bus_type;
- dev->dev.type = &pci_dev_type;
dev->hdr_type = hdr_type & 0x7f;
dev->multifunction = !!(hdr_type & 0x80);
dev->error_state = pci_channel_io_normal;
@@ -1210,6 +1209,7 @@ struct pci_dev *alloc_pci_dev(void)
return NULL;
INIT_LIST_HEAD(&dev->bus_list);
+ dev->dev.type = &pci_dev_type;
return dev;
}
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 0b009470e6db..08126087ec31 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -46,9 +46,7 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
static ssize_t
proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
- const struct inode *ino = file_inode(file);
- const struct proc_dir_entry *dp = PDE(ino);
- struct pci_dev *dev = dp->data;
+ struct pci_dev *dev = PDE_DATA(file_inode(file));
unsigned int pos = *ppos;
unsigned int cnt, size;
@@ -59,7 +57,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
*/
if (capable(CAP_SYS_ADMIN))
- size = dp->size;
+ size = dev->cfg_size;
else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
size = 128;
else
@@ -133,10 +131,9 @@ static ssize_t
proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos)
{
struct inode *ino = file_inode(file);
- const struct proc_dir_entry *dp = PDE(ino);
- struct pci_dev *dev = dp->data;
+ struct pci_dev *dev = PDE_DATA(ino);
int pos = *ppos;
- int size = dp->size;
+ int size = dev->cfg_size;
int cnt;
if (pos >= size)
@@ -200,7 +197,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
pci_config_pm_runtime_put(dev);
*ppos = pos;
- i_size_write(ino, dp->size);
+ i_size_write(ino, dev->cfg_size);
return nbytes;
}
@@ -212,8 +209,7 @@ struct pci_filp_private {
static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
- const struct proc_dir_entry *dp = PDE(file_inode(file));
- struct pci_dev *dev = dp->data;
+ struct pci_dev *dev = PDE_DATA(file_inode(file));
#ifdef HAVE_PCI_MMAP
struct pci_filp_private *fpriv = file->private_data;
#endif /* HAVE_PCI_MMAP */
@@ -253,9 +249,7 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
#ifdef HAVE_PCI_MMAP
static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
{
- struct inode *inode = file_inode(file);
- const struct proc_dir_entry *dp = PDE(inode);
- struct pci_dev *dev = dp->data;
+ struct pci_dev *dev = PDE_DATA(file_inode(file));
struct pci_filp_private *fpriv = file->private_data;
int i, ret;
@@ -425,7 +419,7 @@ int pci_proc_attach_device(struct pci_dev *dev)
&proc_bus_pci_operations, dev);
if (!e)
return -ENOMEM;
- e->size = dev->cfg_size;
+ proc_set_size(e, dev->cfg_size);
dev->procent = e;
return 0;
@@ -433,20 +427,14 @@ int pci_proc_attach_device(struct pci_dev *dev)
int pci_proc_detach_device(struct pci_dev *dev)
{
- struct proc_dir_entry *e;
-
- if ((e = dev->procent)) {
- remove_proc_entry(e->name, dev->bus->procdir);
- dev->procent = NULL;
- }
+ proc_remove(dev->procent);
+ dev->procent = NULL;
return 0;
}
int pci_proc_detach_bus(struct pci_bus* bus)
{
- struct proc_dir_entry *de = bus->procdir;
- if (de)
- remove_proc_entry(de->name, proc_bus_pci_dir);
+ proc_remove(bus->procdir);
return 0;
}