Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Sep 2016 05:51:11 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r306480 - head/sys/compat/linuxkpi/common/include/linux
Message-ID:  <201609300551.u8U5pBPc083539@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Fri Sep 30 05:51:11 2016
New Revision: 306480
URL: https://svnweb.freebsd.org/changeset/base/306480

Log:
  linuxkpi: Fix PCI BAR lazy allocation support.
  
  FreeBSD supports lazy allocation of PCI BAR, that is, when a device
  driver's attach method is invoked, even if the device's PCI BAR
  address wasn't initialized, the invocation of bus_alloc_resource_any()
  (the call chain: pci_alloc_resource() -> pci_alloc_multi_resource() ->
  pci_reserve_map() -> pci_write_bar()) would allocate a proper address
  for the PCI BAR and write this 'lazy allocated' address into the PCI
  BAR.
  
  This model works fine for native FreeBSD device drivers, but _not_ for
  device drivers shared with Linux (e.g. dev/mlx5/mlx5_core/mlx5_main.c
  and ofed/drivers/net/mlx4/main.c.  Both of them use
  pci_request_regions(), which doesn't work properly with the PCI BAR
  lazy allocation, because pci_resource_type() -> _pci_get_rle() always
  returns NULL, so pci_request_regions() doesn't have the opportunity to
  invoke bus_alloc_resource_any().  We now use pci_find_bar() in
  pci_resource_type(), which is able to locate all available PCI BARs
  even if some of them will be lazy allocated.
  
  Submitted by:	Dexuan Cui <decui microsoft com>
  Reviewed by:	hps
  MFC after:	1 week
  Sponsored by:	Microsoft
  Differential Revision:	https://reviews.freebsd.org/D8071

Modified:
  head/sys/compat/linuxkpi/common/include/linux/pci.h

Modified: head/sys/compat/linuxkpi/common/include/linux/pci.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/linux/pci.h	Fri Sep 30 05:30:16 2016	(r306479)
+++ head/sys/compat/linuxkpi/common/include/linux/pci.h	Fri Sep 30 05:51:11 2016	(r306480)
@@ -233,11 +233,16 @@ pci_resource_len(struct pci_dev *pdev, i
 static inline int
 pci_resource_type(struct pci_dev *pdev, int bar)
 {
-	struct resource_list_entry *rle;
+	struct pci_map *pm;
 
-	if ((rle = _pci_get_bar(pdev, bar)) == NULL)
+	pm = pci_find_bar(pdev->dev.bsddev, PCIR_BAR(bar));
+	if (!pm)
 		return (-1);
-	return (rle->type);
+
+	if (PCI_BAR_IO(pm->pm_value))
+		return (SYS_RES_IOPORT);
+	else
+		return (SYS_RES_MEMORY);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609300551.u8U5pBPc083539>