summaryrefslogtreecommitdiffstats
path: root/drivers/virtio
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2015-06-24 01:54:15 -0400
committerMichael S. Tsirkin <mst@redhat.com>2015-06-24 02:15:09 -0400
commit59a5b0f7bf74f88da6670bcbf924d8cc1e75b1ee (patch)
tree37e2f1dba713b5d1b835d05b3acf8d560678abbe /drivers/virtio
parent8b8e658b16336f0f50aba733f51db636ef121f50 (diff)
virtio-pci: alloc only resources actually used.
Move resource allocation from common code to legacy and modern code. Only request resources actually used, i.e. bar0 in legacy mode and the bar(s) specified by capabilities in modern mode. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/virtio')
-rw-r--r--drivers/virtio/virtio_pci_common.c7
-rw-r--r--drivers/virtio/virtio_pci_common.h2
-rw-r--r--drivers/virtio/virtio_pci_legacy.c13
-rw-r--r--drivers/virtio/virtio_pci_modern.c24
4 files changed, 32 insertions, 14 deletions
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index e894eb278d83..4fd036c3468f 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -509,10 +509,6 @@ static int virtio_pci_probe(struct pci_dev *pci_dev,
509 if (rc) 509 if (rc)
510 goto err_enable_device; 510 goto err_enable_device;
511 511
512 rc = pci_request_regions(pci_dev, "virtio-pci");
513 if (rc)
514 goto err_request_regions;
515
516 if (force_legacy) { 512 if (force_legacy) {
517 rc = virtio_pci_legacy_probe(vp_dev); 513 rc = virtio_pci_legacy_probe(vp_dev);
518 /* Also try modern mode if we can't map BAR0 (no IO space). */ 514 /* Also try modern mode if we can't map BAR0 (no IO space). */
@@ -542,8 +538,6 @@ err_register:
542 else 538 else
543 virtio_pci_modern_remove(vp_dev); 539 virtio_pci_modern_remove(vp_dev);
544err_probe: 540err_probe:
545 pci_release_regions(pci_dev);
546err_request_regions:
547 pci_disable_device(pci_dev); 541 pci_disable_device(pci_dev);
548err_enable_device: 542err_enable_device:
549 kfree(vp_dev); 543 kfree(vp_dev);
@@ -561,7 +555,6 @@ static void virtio_pci_remove(struct pci_dev *pci_dev)
561 else 555 else
562 virtio_pci_modern_remove(vp_dev); 556 virtio_pci_modern_remove(vp_dev);
563 557
564 pci_release_regions(pci_dev);
565 pci_disable_device(pci_dev); 558 pci_disable_device(pci_dev);
566} 559}
567 560
diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h
index 28ee4e56badf..b976d968e793 100644
--- a/drivers/virtio/virtio_pci_common.h
+++ b/drivers/virtio/virtio_pci_common.h
@@ -75,6 +75,8 @@ struct virtio_pci_device {
75 /* Multiply queue_notify_off by this value. (non-legacy mode). */ 75 /* Multiply queue_notify_off by this value. (non-legacy mode). */
76 u32 notify_offset_multiplier; 76 u32 notify_offset_multiplier;
77 77
78 int modern_bars;
79
78 /* Legacy only field */ 80 /* Legacy only field */
79 /* the IO mapping for the PCI config space */ 81 /* the IO mapping for the PCI config space */
80 void __iomem *ioaddr; 82 void __iomem *ioaddr;
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c
index 256a5278a515..48bc9797e530 100644
--- a/drivers/virtio/virtio_pci_legacy.c
+++ b/drivers/virtio/virtio_pci_legacy.c
@@ -215,6 +215,7 @@ static const struct virtio_config_ops virtio_pci_config_ops = {
215int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev) 215int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev)
216{ 216{
217 struct pci_dev *pci_dev = vp_dev->pci_dev; 217 struct pci_dev *pci_dev = vp_dev->pci_dev;
218 int rc;
218 219
219 /* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */ 220 /* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */
220 if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f) 221 if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f)
@@ -226,9 +227,14 @@ int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev)
226 return -ENODEV; 227 return -ENODEV;
227 } 228 }
228 229
230 rc = pci_request_region(pci_dev, 0, "virtio-pci-legacy");
231 if (rc)
232 return rc;
233
234 rc = -ENOMEM;
229 vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0); 235 vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0);
230 if (!vp_dev->ioaddr) 236 if (!vp_dev->ioaddr)
231 return -ENOMEM; 237 goto err_iomap;
232 238
233 vp_dev->isr = vp_dev->ioaddr + VIRTIO_PCI_ISR; 239 vp_dev->isr = vp_dev->ioaddr + VIRTIO_PCI_ISR;
234 240
@@ -246,6 +252,10 @@ int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev)
246 vp_dev->del_vq = del_vq; 252 vp_dev->del_vq = del_vq;
247 253
248 return 0; 254 return 0;
255
256err_iomap:
257 pci_release_region(pci_dev, 0);
258 return rc;
249} 259}
250 260
251void virtio_pci_legacy_remove(struct virtio_pci_device *vp_dev) 261void virtio_pci_legacy_remove(struct virtio_pci_device *vp_dev)
@@ -253,4 +263,5 @@ void virtio_pci_legacy_remove(struct virtio_pci_device *vp_dev)
253 struct pci_dev *pci_dev = vp_dev->pci_dev; 263 struct pci_dev *pci_dev = vp_dev->pci_dev;
254 264
255 pci_iounmap(pci_dev, vp_dev->ioaddr); 265 pci_iounmap(pci_dev, vp_dev->ioaddr);
266 pci_release_region(pci_dev, 0);
256} 267}
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index e88e0997a889..8e5cf194cc0b 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -499,7 +499,7 @@ static const struct virtio_config_ops virtio_pci_config_ops = {
499 * Returns offset of the capability, or 0. 499 * Returns offset of the capability, or 0.
500 */ 500 */
501static inline int virtio_pci_find_capability(struct pci_dev *dev, u8 cfg_type, 501static inline int virtio_pci_find_capability(struct pci_dev *dev, u8 cfg_type,
502 u32 ioresource_types) 502 u32 ioresource_types, int *bars)
503{ 503{
504 int pos; 504 int pos;
505 505
@@ -520,8 +520,10 @@ static inline int virtio_pci_find_capability(struct pci_dev *dev, u8 cfg_type,
520 520
521 if (type == cfg_type) { 521 if (type == cfg_type) {
522 if (pci_resource_len(dev, bar) && 522 if (pci_resource_len(dev, bar) &&
523 pci_resource_flags(dev, bar) & ioresource_types) 523 pci_resource_flags(dev, bar) & ioresource_types) {
524 *bars |= (1 << bar);
524 return pos; 525 return pos;
526 }
525 } 527 }
526 } 528 }
527 return 0; 529 return 0;
@@ -617,7 +619,8 @@ int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
617 619
618 /* check for a common config: if not, use legacy mode (bar 0). */ 620 /* check for a common config: if not, use legacy mode (bar 0). */
619 common = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_COMMON_CFG, 621 common = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_COMMON_CFG,
620 IORESOURCE_IO | IORESOURCE_MEM); 622 IORESOURCE_IO | IORESOURCE_MEM,
623 &vp_dev->modern_bars);
621 if (!common) { 624 if (!common) {
622 dev_info(&pci_dev->dev, 625 dev_info(&pci_dev->dev,
623 "virtio_pci: leaving for legacy driver\n"); 626 "virtio_pci: leaving for legacy driver\n");
@@ -626,9 +629,11 @@ int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
626 629
627 /* If common is there, these should be too... */ 630 /* If common is there, these should be too... */
628 isr = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_ISR_CFG, 631 isr = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_ISR_CFG,
629 IORESOURCE_IO | IORESOURCE_MEM); 632 IORESOURCE_IO | IORESOURCE_MEM,
633 &vp_dev->modern_bars);
630 notify = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_NOTIFY_CFG, 634 notify = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_NOTIFY_CFG,
631 IORESOURCE_IO | IORESOURCE_MEM); 635 IORESOURCE_IO | IORESOURCE_MEM,
636 &vp_dev->modern_bars);
632 if (!isr || !notify) { 637 if (!isr || !notify) {
633 dev_err(&pci_dev->dev, 638 dev_err(&pci_dev->dev,
634 "virtio_pci: missing capabilities %i/%i/%i\n", 639 "virtio_pci: missing capabilities %i/%i/%i\n",
@@ -640,7 +645,13 @@ int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
640 * device-specific configuration. 645 * device-specific configuration.
641 */ 646 */
642 device = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_DEVICE_CFG, 647 device = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_DEVICE_CFG,
643 IORESOURCE_IO | IORESOURCE_MEM); 648 IORESOURCE_IO | IORESOURCE_MEM,
649 &vp_dev->modern_bars);
650
651 err = pci_request_selected_regions(pci_dev, vp_dev->modern_bars,
652 "virtio-pci-modern");
653 if (err)
654 return err;
644 655
645 err = -EINVAL; 656 err = -EINVAL;
646 vp_dev->common = map_capability(pci_dev, common, 657 vp_dev->common = map_capability(pci_dev, common,
@@ -727,4 +738,5 @@ void virtio_pci_modern_remove(struct virtio_pci_device *vp_dev)
727 pci_iounmap(pci_dev, vp_dev->notify_base); 738 pci_iounmap(pci_dev, vp_dev->notify_base);
728 pci_iounmap(pci_dev, vp_dev->isr); 739 pci_iounmap(pci_dev, vp_dev->isr);
729 pci_iounmap(pci_dev, vp_dev->common); 740 pci_iounmap(pci_dev, vp_dev->common);
741 pci_release_selected_regions(pci_dev, vp_dev->modern_bars);
730} 742}