From patchwork Thu Jun 11 16:22:22 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jake Oshins X-Patchwork-Id: 6589661 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 944A59F399 for ; Thu, 11 Jun 2015 16:30:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7DB7220631 for ; Thu, 11 Jun 2015 16:30:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5A04C2062A for ; Thu, 11 Jun 2015 16:30:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754647AbbFKQaK (ORCPT ); Thu, 11 Jun 2015 12:30:10 -0400 Received: from o1.f.az.sendgrid.net ([208.117.55.132]:57867 "EHLO o1.f.az.sendgrid.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754771AbbFKQ37 (ORCPT ); Thu, 11 Jun 2015 12:29:59 -0400 X-Greylist: delayed 300 seconds by postgrey-1.27 at vger.kernel.org; Thu, 11 Jun 2015 12:29:53 EDT DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sendgrid.me; h=from:to:cc:subject:in-reply-to:references; s=smtpapi; bh=VSGC1LCNplHFQKcdmR2efYnqTMo=; b=ssgNR5WTOiU4Ln5y4JzfKSpiN//+2 jOOFxOw7FEKNKAUZK4to+y8GfG/gLrLnKvPRq04atusQTQ0Iif8/2AXvJoGjduv5 tssO8Pkdc1zOs/f36Rs/oMfFKBQMvnIrdS0XnDUoEDCBaM7Kp1foUHn2UeMdxutS hWe1syxHn5eg4Y= Received: by filter-482.sjc1.sendgrid.net with SMTP id filter-482.308.5579B616A 2015-06-11 16:23:50.123215284 +0000 UTC Received: from jakeoshinsu2.jakeoshinsu2.d1.internal.cloudapp.net (unknown [104.210.40.47]) by ismtpd-049 (SG) with ESMTP id 14de36f45fe.4707.56f07 Thu, 11 Jun 2015 16:23:50 +0000 (UTC) From: jakeo@microsoft.com To: gregkh@linuxfoundation.org, kys@microsoft.com, linux-kernel@vger.kernel.org, devel@linuxdriverproject.org, olaf@aepfle.de, apw@canonical.com, vkuznets@redhat.com, linux-pci@vger.kernel.org, bhelgaas@google.com, mebersol@microsoft.com, haiyangz@microsoft.com Cc: Jake Oshins Subject: [PATCH 1/6] drivers:hv: Modify vmbus to search for all MMIO ranges available Date: Thu, 11 Jun 2015 16:22:22 +0000 Message-Id: <1434039747-44535-2-git-send-email-jakeo@microsoft.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1434039747-44535-1-git-send-email-jakeo@microsoft.com> References: <1434039747-44535-1-git-send-email-jakeo@microsoft.com> X-SG-EID: lfnueJVzSjg1mfuVqqukVH7tZvRy9mfCIcBnfbfzaMNLVSAQx+U2XNA0W2Qy3CvX0sxynBsXqtpGah 1EWRjAUtFyutGvFYQyJcZ/qJg6C+KTUcKTdSfX33g+vzSwLsQc/re/e68DHu10Gsn+Iqco6jOjohxb Qvp4YcG51Ipnv38= Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY, URIBL_GREY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Jake Oshins Signed-off-by: Jake Oshins --- drivers/hv/vmbus_drv.c | 105 ++++++++++++++++++++++++++++++++++------ drivers/video/fbdev/hyperv_fb.c | 2 +- include/linux/hyperv.h | 2 +- 3 files changed, 92 insertions(+), 17 deletions(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index c85235e..d0e8832 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -72,10 +72,7 @@ static struct notifier_block hyperv_panic_block = { .notifier_call = hyperv_panic_event, }; -struct resource hyperv_mmio = { - .name = "hyperv mmio", - .flags = IORESOURCE_MEM, -}; +struct resource *hyperv_mmio; EXPORT_SYMBOL_GPL(hyperv_mmio); static int vmbus_exists(void) @@ -982,30 +979,105 @@ void vmbus_device_unregister(struct hv_device *device_obj) /* - * VMBUS is an acpi enumerated device. Get the the information we + * VMBUS is an acpi enumerated device. Get the information we * need from DSDT. */ - +#define VTPM_BASE_ADDRESS 0xfed40000 static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) { + resource_size_t start = 0; + resource_size_t end = 0; + struct resource *new_res; + struct resource **old_res = &hyperv_mmio; + struct resource **prev_res = NULL; + switch (res->type) { case ACPI_RESOURCE_TYPE_IRQ: irq = res->data.irq.interrupts[0]; + return AE_OK; + + /* + * "Address" descriptors are for bus windows. Ignore + * "memory" descriptors, which are for registers on + * devices. + */ + case ACPI_RESOURCE_TYPE_ADDRESS32: + start = res->data.address32.address.minimum; + end = res->data.address32.address.maximum; break; case ACPI_RESOURCE_TYPE_ADDRESS64: - hyperv_mmio.start = res->data.address64.address.minimum; - hyperv_mmio.end = res->data.address64.address.maximum; + start = res->data.address64.address.minimum; + end = res->data.address64.address.maximum; break; + + default: + /* Unused resource type */ + return AE_OK; + } + /* + * Ignore ranges that are below 1MB, as they're not + * necessary or useful here. + */ + if (end < 0x100000) + return AE_OK; + + new_res = kzalloc(sizeof(*new_res), GFP_ATOMIC); + if (!new_res) + return AE_NO_MEMORY; + + /* If this range overlaps the virtual TPM, truncate it. */ + if (end > VTPM_BASE_ADDRESS && start < VTPM_BASE_ADDRESS) + end = VTPM_BASE_ADDRESS; + + new_res->name = "hyperv mmio"; + new_res->flags = IORESOURCE_MEM; + new_res->start = start; + new_res->end = end; + + do { + if (!*old_res) { + *old_res = new_res; + break; + } + + if ((*old_res)->end < new_res->start) { + new_res->sibling = *old_res; + if (prev_res) + (*prev_res)->sibling = new_res; + *old_res = new_res; + break; + } + + prev_res = old_res; + old_res = &(*old_res)->sibling; + + } while (1); return AE_OK; } +static int vmbus_acpi_remove(struct acpi_device *device) +{ + struct resource *cur_res; + struct resource *next_res; + + if (hyperv_mmio) { + for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) { + next_res = cur_res->sibling; + kfree(cur_res); + } + } + + return 0; +} + static int vmbus_acpi_add(struct acpi_device *device) { acpi_status result; int ret_val = -ENODEV; + struct acpi_device *ancestor; hv_acpi_dev = device; @@ -1015,23 +1087,25 @@ static int vmbus_acpi_add(struct acpi_device *device) if (ACPI_FAILURE(result)) goto acpi_walk_err; /* - * The parent of the vmbus acpi device (Gen2 firmware) is the VMOD that - * has the mmio ranges. Get that. + * Some ancestor of the vmbus acpi device (Gen1 or Gen2 + * firmware) is the VMOD that has the mmio ranges. Get that. */ - if (device->parent) { - result = acpi_walk_resources(device->parent->handle, + for (ancestor = device->parent; ancestor; ancestor = ancestor->parent) { + result = acpi_walk_resources(ancestor->handle, METHOD_NAME__CRS, vmbus_walk_resources, NULL); if (ACPI_FAILURE(result)) - goto acpi_walk_err; - if (hyperv_mmio.start && hyperv_mmio.end) - request_resource(&iomem_resource, &hyperv_mmio); + continue; + if (hyperv_mmio) + break; } ret_val = 0; acpi_walk_err: complete(&probe_event); + if (ret_val) + vmbus_acpi_remove(device); return ret_val; } @@ -1047,6 +1121,7 @@ static struct acpi_driver vmbus_acpi_driver = { .ids = vmbus_acpi_device_ids, .ops = { .add = vmbus_acpi_add, + .remove = vmbus_acpi_remove, }, }; diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index 807ee22..b54ee1c 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -688,7 +688,7 @@ static int hvfb_getmem(struct fb_info *info) par->mem.name = KBUILD_MODNAME; par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY; if (gen2vm) { - ret = allocate_resource(&hyperv_mmio, &par->mem, + ret = allocate_resource(hyperv_mmio, &par->mem, screen_fb_size, 0, -1, screen_fb_size, diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 902c37a..21fa867 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1245,7 +1245,7 @@ void hv_vss_deinit(void); void hv_vss_onchannelcallback(void *); void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid); -extern struct resource hyperv_mmio; +extern struct resource *hyperv_mmio; /* * Negotiated version with the Host.