diff options
| -rw-r--r-- | Documentation/PCI/pci-iov-howto.txt | 4 | ||||
| -rw-r--r-- | drivers/pci/iov.c | 119 | ||||
| -rw-r--r-- | drivers/pci/pci.h | 4 | ||||
| -rw-r--r-- | include/linux/pci.h | 4 |
4 files changed, 0 insertions, 131 deletions
diff --git a/Documentation/PCI/pci-iov-howto.txt b/Documentation/PCI/pci-iov-howto.txt index 86551cc72e03..2d91ae251982 100644 --- a/Documentation/PCI/pci-iov-howto.txt +++ b/Documentation/PCI/pci-iov-howto.txt | |||
| @@ -68,10 +68,6 @@ To disable SR-IOV capability: | |||
| 68 | echo 0 > \ | 68 | echo 0 > \ |
| 69 | /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs | 69 | /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs |
| 70 | 70 | ||
| 71 | To notify SR-IOV core of Virtual Function Migration: | ||
| 72 | (a) In the driver: | ||
| 73 | irqreturn_t pci_sriov_migration(struct pci_dev *dev); | ||
| 74 | |||
| 75 | 3.2 Usage example | 71 | 3.2 Usage example |
| 76 | 72 | ||
| 77 | Following piece of code illustrates the usage of the SR-IOV API. | 73 | Following piece of code illustrates the usage of the SR-IOV API. |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 9dce7c5e2a77..de7a74782f92 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
| @@ -170,97 +170,6 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset) | |||
| 170 | pci_dev_put(dev); | 170 | pci_dev_put(dev); |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | static int sriov_migration(struct pci_dev *dev) | ||
| 174 | { | ||
| 175 | u16 status; | ||
| 176 | struct pci_sriov *iov = dev->sriov; | ||
| 177 | |||
| 178 | if (!iov->num_VFs) | ||
| 179 | return 0; | ||
| 180 | |||
| 181 | if (!(iov->cap & PCI_SRIOV_CAP_VFM)) | ||
| 182 | return 0; | ||
| 183 | |||
| 184 | pci_read_config_word(dev, iov->pos + PCI_SRIOV_STATUS, &status); | ||
| 185 | if (!(status & PCI_SRIOV_STATUS_VFM)) | ||
| 186 | return 0; | ||
| 187 | |||
| 188 | schedule_work(&iov->mtask); | ||
| 189 | |||
| 190 | return 1; | ||
| 191 | } | ||
| 192 | |||
| 193 | static void sriov_migration_task(struct work_struct *work) | ||
| 194 | { | ||
| 195 | int i; | ||
| 196 | u8 state; | ||
| 197 | u16 status; | ||
| 198 | struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask); | ||
| 199 | |||
| 200 | for (i = iov->initial_VFs; i < iov->num_VFs; i++) { | ||
| 201 | state = readb(iov->mstate + i); | ||
| 202 | if (state == PCI_SRIOV_VFM_MI) { | ||
| 203 | writeb(PCI_SRIOV_VFM_AV, iov->mstate + i); | ||
| 204 | state = readb(iov->mstate + i); | ||
| 205 | if (state == PCI_SRIOV_VFM_AV) | ||
| 206 | virtfn_add(iov->self, i, 1); | ||
| 207 | } else if (state == PCI_SRIOV_VFM_MO) { | ||
| 208 | virtfn_remove(iov->self, i, 1); | ||
| 209 | writeb(PCI_SRIOV_VFM_UA, iov->mstate + i); | ||
| 210 | state = readb(iov->mstate + i); | ||
| 211 | if (state == PCI_SRIOV_VFM_AV) | ||
| 212 | virtfn_add(iov->self, i, 0); | ||
| 213 | } | ||
| 214 | } | ||
| 215 | |||
| 216 | pci_read_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, &status); | ||
| 217 | status &= ~PCI_SRIOV_STATUS_VFM; | ||
| 218 | pci_write_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, status); | ||
| 219 | } | ||
| 220 | |||
| 221 | static int sriov_enable_migration(struct pci_dev *dev, int nr_virtfn) | ||
| 222 | { | ||
| 223 | int bir; | ||
| 224 | u32 table; | ||
| 225 | resource_size_t pa; | ||
| 226 | struct pci_sriov *iov = dev->sriov; | ||
| 227 | |||
| 228 | if (nr_virtfn <= iov->initial_VFs) | ||
| 229 | return 0; | ||
| 230 | |||
| 231 | pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table); | ||
| 232 | bir = PCI_SRIOV_VFM_BIR(table); | ||
| 233 | if (bir > PCI_STD_RESOURCE_END) | ||
| 234 | return -EIO; | ||
| 235 | |||
| 236 | table = PCI_SRIOV_VFM_OFFSET(table); | ||
| 237 | if (table + nr_virtfn > pci_resource_len(dev, bir)) | ||
| 238 | return -EIO; | ||
| 239 | |||
| 240 | pa = pci_resource_start(dev, bir) + table; | ||
| 241 | iov->mstate = ioremap(pa, nr_virtfn); | ||
| 242 | if (!iov->mstate) | ||
| 243 | return -ENOMEM; | ||
| 244 | |||
| 245 | INIT_WORK(&iov->mtask, sriov_migration_task); | ||
| 246 | |||
| 247 | iov->ctrl |= PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR; | ||
| 248 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); | ||
| 249 | |||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 253 | static void sriov_disable_migration(struct pci_dev *dev) | ||
| 254 | { | ||
| 255 | struct pci_sriov *iov = dev->sriov; | ||
| 256 | |||
| 257 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR); | ||
| 258 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); | ||
| 259 | |||
| 260 | cancel_work_sync(&iov->mtask); | ||
| 261 | iounmap(iov->mstate); | ||
| 262 | } | ||
| 263 | |||
| 264 | static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | 173 | static int sriov_enable(struct pci_dev *dev, int nr_virtfn) |
| 265 | { | 174 | { |
| 266 | int rc; | 175 | int rc; |
| @@ -351,12 +260,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
| 351 | goto failed; | 260 | goto failed; |
| 352 | } | 261 | } |
| 353 | 262 | ||
| 354 | if (iov->cap & PCI_SRIOV_CAP_VFM) { | ||
| 355 | rc = sriov_enable_migration(dev, nr_virtfn); | ||
| 356 | if (rc) | ||
| 357 | goto failed; | ||
| 358 | } | ||
| 359 | |||
| 360 | kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); | 263 | kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); |
| 361 | iov->num_VFs = nr_virtfn; | 264 | iov->num_VFs = nr_virtfn; |
| 362 | 265 | ||
| @@ -387,9 +290,6 @@ static void sriov_disable(struct pci_dev *dev) | |||
| 387 | if (!iov->num_VFs) | 290 | if (!iov->num_VFs) |
| 388 | return; | 291 | return; |
| 389 | 292 | ||
| 390 | if (iov->cap & PCI_SRIOV_CAP_VFM) | ||
| 391 | sriov_disable_migration(dev); | ||
| 392 | |||
| 393 | for (i = 0; i < iov->num_VFs; i++) | 293 | for (i = 0; i < iov->num_VFs; i++) |
| 394 | virtfn_remove(dev, i, 0); | 294 | virtfn_remove(dev, i, 0); |
| 395 | 295 | ||
| @@ -688,25 +588,6 @@ void pci_disable_sriov(struct pci_dev *dev) | |||
| 688 | EXPORT_SYMBOL_GPL(pci_disable_sriov); | 588 | EXPORT_SYMBOL_GPL(pci_disable_sriov); |
| 689 | 589 | ||
| 690 | /** | 590 | /** |
| 691 | * pci_sriov_migration - notify SR-IOV core of Virtual Function Migration | ||
| 692 | * @dev: the PCI device | ||
| 693 | * | ||
| 694 | * Returns IRQ_HANDLED if the IRQ is handled, or IRQ_NONE if not. | ||
| 695 | * | ||
| 696 | * Physical Function driver is responsible to register IRQ handler using | ||
| 697 | * VF Migration Interrupt Message Number, and call this function when the | ||
| 698 | * interrupt is generated by the hardware. | ||
| 699 | */ | ||
| 700 | irqreturn_t pci_sriov_migration(struct pci_dev *dev) | ||
| 701 | { | ||
| 702 | if (!dev->is_physfn) | ||
| 703 | return IRQ_NONE; | ||
| 704 | |||
| 705 | return sriov_migration(dev) ? IRQ_HANDLED : IRQ_NONE; | ||
| 706 | } | ||
| 707 | EXPORT_SYMBOL_GPL(pci_sriov_migration); | ||
| 708 | |||
| 709 | /** | ||
| 710 | * pci_num_vf - return number of VFs associated with a PF device_release_driver | 591 | * pci_num_vf - return number of VFs associated with a PF device_release_driver |
| 711 | * @dev: the PCI device | 592 | * @dev: the PCI device |
| 712 | * | 593 | * |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 4df38df224f4..6bd082299e31 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | #ifndef DRIVERS_PCI_H | 1 | #ifndef DRIVERS_PCI_H |
| 2 | #define DRIVERS_PCI_H | 2 | #define DRIVERS_PCI_H |
| 3 | 3 | ||
| 4 | #include <linux/workqueue.h> | ||
| 5 | |||
| 6 | #define PCI_CFG_SPACE_SIZE 256 | 4 | #define PCI_CFG_SPACE_SIZE 256 |
| 7 | #define PCI_CFG_SPACE_EXP_SIZE 4096 | 5 | #define PCI_CFG_SPACE_EXP_SIZE 4096 |
| 8 | 6 | ||
| @@ -240,8 +238,6 @@ struct pci_sriov { | |||
| 240 | struct pci_dev *dev; /* lowest numbered PF */ | 238 | struct pci_dev *dev; /* lowest numbered PF */ |
| 241 | struct pci_dev *self; /* this PF */ | 239 | struct pci_dev *self; /* this PF */ |
| 242 | struct mutex lock; /* lock for VF bus */ | 240 | struct mutex lock; /* lock for VF bus */ |
| 243 | struct work_struct mtask; /* VF Migration task */ | ||
| 244 | u8 __iomem *mstate; /* VF Migration State Array */ | ||
| 245 | }; | 241 | }; |
| 246 | 242 | ||
| 247 | #ifdef CONFIG_PCI_ATS | 243 | #ifdef CONFIG_PCI_ATS |
diff --git a/include/linux/pci.h b/include/linux/pci.h index fb57c892b214..230a8dabc5a3 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include <linux/atomic.h> | 29 | #include <linux/atomic.h> |
| 30 | #include <linux/device.h> | 30 | #include <linux/device.h> |
| 31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
| 32 | #include <linux/irqreturn.h> | ||
| 33 | #include <uapi/linux/pci.h> | 32 | #include <uapi/linux/pci.h> |
| 34 | 33 | ||
| 35 | #include <linux/pci_ids.h> | 34 | #include <linux/pci_ids.h> |
| @@ -1577,7 +1576,6 @@ void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar); | |||
| 1577 | #ifdef CONFIG_PCI_IOV | 1576 | #ifdef CONFIG_PCI_IOV |
| 1578 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); | 1577 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); |
| 1579 | void pci_disable_sriov(struct pci_dev *dev); | 1578 | void pci_disable_sriov(struct pci_dev *dev); |
| 1580 | irqreturn_t pci_sriov_migration(struct pci_dev *dev); | ||
| 1581 | int pci_num_vf(struct pci_dev *dev); | 1579 | int pci_num_vf(struct pci_dev *dev); |
| 1582 | int pci_vfs_assigned(struct pci_dev *dev); | 1580 | int pci_vfs_assigned(struct pci_dev *dev); |
| 1583 | int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); | 1581 | int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); |
| @@ -1586,8 +1584,6 @@ int pci_sriov_get_totalvfs(struct pci_dev *dev); | |||
| 1586 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) | 1584 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) |
| 1587 | { return -ENODEV; } | 1585 | { return -ENODEV; } |
| 1588 | static inline void pci_disable_sriov(struct pci_dev *dev) { } | 1586 | static inline void pci_disable_sriov(struct pci_dev *dev) { } |
| 1589 | static inline irqreturn_t pci_sriov_migration(struct pci_dev *dev) | ||
| 1590 | { return IRQ_NONE; } | ||
| 1591 | static inline int pci_num_vf(struct pci_dev *dev) { return 0; } | 1587 | static inline int pci_num_vf(struct pci_dev *dev) { return 0; } |
| 1592 | static inline int pci_vfs_assigned(struct pci_dev *dev) | 1588 | static inline int pci_vfs_assigned(struct pci_dev *dev) |
| 1593 | { return 0; } | 1589 | { return 0; } |
