RE: [PATCH 4/4] hyperv-fb: add support for generation 2 virtual machines.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Gerd Hoffmann [mailto:kraxel@xxxxxxxxxx]
> Sent: Friday, February 21, 2014 12:57 AM
> To: linux-fbdev@xxxxxxxxxxxxxxx
> Cc: linux-kernel@xxxxxxxxxxxxxxx; gregkh@xxxxxxxxxxxxxxxxxxx; KY Srinivasan;
> Haiyang Zhang; jasowang@xxxxxxxxxx; 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 <haiyangz@xxxxxxxxxxxxx>
> 
> Signed-off-by: Gerd Hoffmann <kraxel@xxxxxxxxxx>
> ---
>  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

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux