diff options
Diffstat (limited to 'drivers/pci/iov.c')
| -rw-r--r-- | drivers/pci/iov.c | 125 | 
1 files changed, 4 insertions, 121 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 21a7182dccd..cb6f24740ee 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -84,6 +84,7 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)  	virtfn->dev.parent = dev->dev.parent;  	virtfn->physfn = pci_dev_get(dev);  	virtfn->is_virtfn = 1; +	virtfn->multifunction = 0;  	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {  		res = dev->resource + PCI_IOV_RESOURCES + i; @@ -105,7 +106,7 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)  	pci_device_add(virtfn, virtfn->bus);  	mutex_unlock(&iov->dev->sriov->lock); -	rc = pci_bus_add_device(virtfn); +	pci_bus_add_device(virtfn);  	sprintf(buf, "virtfn%u", id);  	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);  	if (rc) @@ -169,97 +170,6 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset)  	pci_dev_put(dev);  } -static int sriov_migration(struct pci_dev *dev) -{ -	u16 status; -	struct pci_sriov *iov = dev->sriov; - -	if (!iov->num_VFs) -		return 0; - -	if (!(iov->cap & PCI_SRIOV_CAP_VFM)) -		return 0; - -	pci_read_config_word(dev, iov->pos + PCI_SRIOV_STATUS, &status); -	if (!(status & PCI_SRIOV_STATUS_VFM)) -		return 0; - -	schedule_work(&iov->mtask); - -	return 1; -} - -static void sriov_migration_task(struct work_struct *work) -{ -	int i; -	u8 state; -	u16 status; -	struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask); - -	for (i = iov->initial_VFs; i < iov->num_VFs; i++) { -		state = readb(iov->mstate + i); -		if (state == PCI_SRIOV_VFM_MI) { -			writeb(PCI_SRIOV_VFM_AV, iov->mstate + i); -			state = readb(iov->mstate + i); -			if (state == PCI_SRIOV_VFM_AV) -				virtfn_add(iov->self, i, 1); -		} else if (state == PCI_SRIOV_VFM_MO) { -			virtfn_remove(iov->self, i, 1); -			writeb(PCI_SRIOV_VFM_UA, iov->mstate + i); -			state = readb(iov->mstate + i); -			if (state == PCI_SRIOV_VFM_AV) -				virtfn_add(iov->self, i, 0); -		} -	} - -	pci_read_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, &status); -	status &= ~PCI_SRIOV_STATUS_VFM; -	pci_write_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, status); -} - -static int sriov_enable_migration(struct pci_dev *dev, int nr_virtfn) -{ -	int bir; -	u32 table; -	resource_size_t pa; -	struct pci_sriov *iov = dev->sriov; - -	if (nr_virtfn <= iov->initial_VFs) -		return 0; - -	pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table); -	bir = PCI_SRIOV_VFM_BIR(table); -	if (bir > PCI_STD_RESOURCE_END) -		return -EIO; - -	table = PCI_SRIOV_VFM_OFFSET(table); -	if (table + nr_virtfn > pci_resource_len(dev, bir)) -		return -EIO; - -	pa = pci_resource_start(dev, bir) + table; -	iov->mstate = ioremap(pa, nr_virtfn); -	if (!iov->mstate) -		return -ENOMEM; - -	INIT_WORK(&iov->mtask, sriov_migration_task); - -	iov->ctrl |= PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR; -	pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); - -	return 0; -} - -static void sriov_disable_migration(struct pci_dev *dev) -{ -	struct pci_sriov *iov = dev->sriov; - -	iov->ctrl &= ~(PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR); -	pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); - -	cancel_work_sync(&iov->mtask); -	iounmap(iov->mstate); -} -  static int sriov_enable(struct pci_dev *dev, int nr_virtfn)  {  	int rc; @@ -350,12 +260,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)  			goto failed;  	} -	if (iov->cap & PCI_SRIOV_CAP_VFM) { -		rc = sriov_enable_migration(dev, nr_virtfn); -		if (rc) -			goto failed; -	} -  	kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE);  	iov->num_VFs = nr_virtfn; @@ -386,9 +290,6 @@ static void sriov_disable(struct pci_dev *dev)  	if (!iov->num_VFs)  		return; -	if (iov->cap & PCI_SRIOV_CAP_VFM) -		sriov_disable_migration(dev); -  	for (i = 0; i < iov->num_VFs; i++)  		virtfn_remove(dev, i, 0); @@ -441,6 +342,7 @@ static int sriov_init(struct pci_dev *dev, int pos)  found:  	pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, ctrl); +	pci_write_config_word(dev, pos + PCI_SRIOV_NUM_VF, 0);  	pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);  	pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);  	if (!offset || (total > 1 && !stride)) @@ -610,7 +512,7 @@ resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno)  	struct resource tmp;  	enum pci_bar_type type;  	int reg = pci_iov_resource_bar(dev, resno, &type); -	 +  	if (!reg)  		return 0; @@ -686,25 +588,6 @@ void pci_disable_sriov(struct pci_dev *dev)  EXPORT_SYMBOL_GPL(pci_disable_sriov);  /** - * pci_sriov_migration - notify SR-IOV core of Virtual Function Migration - * @dev: the PCI device - * - * Returns IRQ_HANDLED if the IRQ is handled, or IRQ_NONE if not. - * - * Physical Function driver is responsible to register IRQ handler using - * VF Migration Interrupt Message Number, and call this function when the - * interrupt is generated by the hardware. - */ -irqreturn_t pci_sriov_migration(struct pci_dev *dev) -{ -	if (!dev->is_physfn) -		return IRQ_NONE; - -	return sriov_migration(dev) ? IRQ_HANDLED : IRQ_NONE; -} -EXPORT_SYMBOL_GPL(pci_sriov_migration); - -/**   * pci_num_vf - return number of VFs associated with a PF device_release_driver   * @dev: the PCI device   *  | 
