diff options
Diffstat (limited to 'drivers/misc/vmw_vmci/vmci_guest.c')
-rw-r--r-- | drivers/misc/vmw_vmci/vmci_guest.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c index dad5abee656e..928708128177 100644 --- a/drivers/misc/vmw_vmci/vmci_guest.c +++ b/drivers/misc/vmw_vmci/vmci_guest.c @@ -64,6 +64,13 @@ struct vmci_guest_device { dma_addr_t notification_base; }; +static bool use_ppn64; + +bool vmci_use_ppn64(void) +{ + return use_ppn64; +} + /* vmci_dev singleton device and supporting data*/ struct pci_dev *vmci_pdev; static struct vmci_guest_device *vmci_dev_g; @@ -432,6 +439,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, struct vmci_guest_device *vmci_dev; void __iomem *iobase; unsigned int capabilities; + unsigned int caps_in_use; unsigned long cmd; int vmci_err; int error; @@ -496,6 +504,23 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, error = -ENXIO; goto err_free_data_buffer; } + caps_in_use = VMCI_CAPS_DATAGRAM; + + /* + * Use 64-bit PPNs if the device supports. + * + * There is no check for the return value of dma_set_mask_and_coherent + * since this driver can handle the default mask values if + * dma_set_mask_and_coherent fails. + */ + if (capabilities & VMCI_CAPS_PPN64) { + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + use_ppn64 = true; + caps_in_use |= VMCI_CAPS_PPN64; + } else { + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44)); + use_ppn64 = false; + } /* * If the hardware supports notifications, we will use that as @@ -510,14 +535,14 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, "Unable to allocate notification bitmap\n"); } else { memset(vmci_dev->notification_bitmap, 0, PAGE_SIZE); - capabilities |= VMCI_CAPS_NOTIFICATIONS; + caps_in_use |= VMCI_CAPS_NOTIFICATIONS; } } - dev_info(&pdev->dev, "Using capabilities 0x%x\n", capabilities); + dev_info(&pdev->dev, "Using capabilities 0x%x\n", caps_in_use); /* Let the host know which capabilities we intend to use. */ - iowrite32(capabilities, vmci_dev->iobase + VMCI_CAPS_ADDR); + iowrite32(caps_in_use, vmci_dev->iobase + VMCI_CAPS_ADDR); /* Set up global device so that we can start sending datagrams */ spin_lock_irq(&vmci_dev_spinlock); @@ -529,13 +554,13 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, * Register notification bitmap with device if that capability is * used. */ - if (capabilities & VMCI_CAPS_NOTIFICATIONS) { + if (caps_in_use & VMCI_CAPS_NOTIFICATIONS) { unsigned long bitmap_ppn = vmci_dev->notification_base >> PAGE_SHIFT; if (!vmci_dbell_register_notification_bitmap(bitmap_ppn)) { dev_warn(&pdev->dev, - "VMCI device unable to register notification bitmap with PPN 0x%x\n", - (u32) bitmap_ppn); + "VMCI device unable to register notification bitmap with PPN 0x%lx\n", + bitmap_ppn); error = -ENXIO; goto err_remove_vmci_dev_g; } @@ -611,7 +636,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, /* Enable specific interrupt bits. */ cmd = VMCI_IMR_DATAGRAM; - if (capabilities & VMCI_CAPS_NOTIFICATIONS) + if (caps_in_use & VMCI_CAPS_NOTIFICATIONS) cmd |= VMCI_IMR_NOTIFICATION; iowrite32(cmd, vmci_dev->iobase + VMCI_IMR_ADDR); |