> -----Original Message-----
> From: Gerd Hoffmann [mailto:kra...@redhat.com]
> Sent: Friday, February 21, 2014 12:57 AM
> To: linux-fb...@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org; gre...@linuxfoundation.org; KY Srinivasan;
> Haiyang Zhang; jasow...@redhat.com; Gerd Hoffmann; Jean-Christophe
> Plagniol-Villard; Tomi Valkeinen; open list:Hyper-V CORE AND...
> Subject: [PATCH 4/4] hyperv-fb: add support for generation 2 virtual machines.
> 
> UEFI-based generation 2 virtual machines support vmbus devices only.
> There is no pci bus.  Thus they use a different mechanism for the
> graphics framebuffer:  Instead of using the vga pci bar a chunk of
> memory muct be allocated from the hyperv mmio region declared using
> APCI.  This patch implements support for it.
> 
> Based on a patch by Haiyang Zhang <haiya...@microsoft.com>
> 
> Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
> ---
>  drivers/video/hyperv_fb.c | 86 +++++++++++++++++++++++++++++++++-------
> -------
>  1 file changed, 60 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c
> index 130708f..f956cd9 100644
> --- a/drivers/video/hyperv_fb.c
> +++ b/drivers/video/hyperv_fb.c
> @@ -42,6 +42,7 @@
>  #include <linux/completion.h>
>  #include <linux/fb.h>
>  #include <linux/pci.h>
> +#include <linux/efi.h>
> 
>  #include <linux/hyperv.h>
> 
> @@ -212,6 +213,7 @@ struct synthvid_msg {
> 
>  struct hvfb_par {
>       struct fb_info *info;
> +     struct resource mem;
>       bool fb_ready; /* fb device is ready */
>       struct completion wait;
>       u32 synthvid_version;
> @@ -460,13 +462,13 @@ static int synthvid_connect_vsp(struct hv_device
> *hdev)
>               goto error;
>       }
> 
> -     if (par->synthvid_version == SYNTHVID_VERSION_WIN7) {
> +     if (par->synthvid_version == SYNTHVID_VERSION_WIN7)
>               screen_depth = SYNTHVID_DEPTH_WIN7;
> -             screen_fb_size = SYNTHVID_FB_SIZE_WIN7;
> -     } else {
> +     else
>               screen_depth = SYNTHVID_DEPTH_WIN8;
> -             screen_fb_size = SYNTHVID_FB_SIZE_WIN8;
> -     }
> +
> +     screen_fb_size = hdev->channel->offermsg.offer.
> +                             mmio_megabytes * 1024 * 1024;
> 
>       return 0;
> 
> @@ -627,26 +629,46 @@ static void hvfb_get_option(struct fb_info *info)
>  /* Get framebuffer memory from Hyper-V video pci space */
>  static int hvfb_getmem(struct fb_info *info)
>  {
> -     struct pci_dev *pdev;
> -     ulong fb_phys;
> +     struct hvfb_par *par = info->par;
> +     struct pci_dev *pdev  = NULL;
>       void __iomem *fb_virt;
> +     bool gen2vm = efi_enabled(EFI_BOOT);

Gerd,
efi_enabled() returns an int and not a bool. That is the fix that Haiyang made 
last night.

K. Y
> +     int ret;
> 
> -     pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
> +     par->mem.name = "hyperv_fb";
> +     par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
> +     if (gen2vm) {
> +             ret = allocate_resource(&hyperv_mmio, &par->mem,
> +                                     screen_fb_size,
> +                                     0, -1,
> +                                     screen_fb_size,
> +                                     NULL, NULL);
> +             if (ret != 0) {
> +                     pr_err("Unable to allocate framebuffer memory\n");
> +                     return -ENODEV;
> +             }
> +     } else {
> +             pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
>                             PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
> -     if (!pdev) {
> -             pr_err("Unable to find PCI Hyper-V video\n");
> -             return -ENODEV;
> -     }
> +             if (!pdev) {
> +                     pr_err("Unable to find PCI Hyper-V video\n");
> +                     return -ENODEV;
> +             }
> 
> -     if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
> -         pci_resource_len(pdev, 0) < screen_fb_size)
> -             goto err1;
> +             if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
> +                 pci_resource_len(pdev, 0) < screen_fb_size)
> +                     goto err1;
> 
> -     fb_phys = pci_resource_end(pdev, 0) - screen_fb_size + 1;
> -     if (!request_mem_region(fb_phys, screen_fb_size,
> KBUILD_MODNAME))
> -             goto err1;
> +             par->mem.end = pci_resource_end(pdev, 0);
> +             par->mem.start = par->mem.end - screen_fb_size + 1;
> +             ret = request_resource(&pdev->resource[0], &par->mem);
> +             if (ret != 0) {
> +                     pr_err("Unable to request framebuffer memory\n");
> +                     return -ENODEV;
> +             }
> +     }
> 
> -     fb_virt = ioremap(fb_phys, screen_fb_size);
> +     fb_virt = ioremap(par->mem.start, screen_fb_size);
>       if (!fb_virt)
>               goto err2;
> 
> @@ -654,30 +676,42 @@ static int hvfb_getmem(struct fb_info *info)
>       if (!info->apertures)
>               goto err3;
> 
> -     info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
> -     info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
> -     info->fix.smem_start = fb_phys;
> +     if (gen2vm) {
> +             info->apertures->ranges[0].base = screen_info.lfb_base;
> +             info->apertures->ranges[0].size = screen_info.lfb_size;
> +     } else {
> +             info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
> +             info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
> +     }
> +
> +     info->fix.smem_start = par->mem.start;
>       info->fix.smem_len = screen_fb_size;
>       info->screen_base = fb_virt;
>       info->screen_size = screen_fb_size;
> 
> -     pci_dev_put(pdev);
> +     if (!gen2vm)
> +             pci_dev_put(pdev);
> +
>       return 0;
> 
>  err3:
>       iounmap(fb_virt);
>  err2:
> -     release_mem_region(fb_phys, screen_fb_size);
> +     release_resource(&par->mem);
>  err1:
> -     pci_dev_put(pdev);
> +     if (!gen2vm)
> +             pci_dev_put(pdev);
> +
>       return -ENOMEM;
>  }
> 
>  /* Release the framebuffer */
>  static void hvfb_putmem(struct fb_info *info)
>  {
> +     struct hvfb_par *par = info->par;
> +
>       iounmap(info->screen_base);
> -     release_mem_region(info->fix.smem_start, screen_fb_size);
> +     release_resource(&par->mem);
>  }
> 
> 
> --
> 1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to