From nobody@FreeBSD.org  Thu Aug  5 04:42:56 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id CC4A41065677
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  5 Aug 2010 04:42:56 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id A30B88FC2D
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  5 Aug 2010 04:42:56 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o754gu9w033189
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 5 Aug 2010 04:42:56 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o754guPJ033188;
	Thu, 5 Aug 2010 04:42:56 GMT
	(envelope-from nobody)
Message-Id: <201008050442.o754guPJ033188@www.freebsd.org>
Date: Thu, 5 Aug 2010 04:42:56 GMT
From: KsenZ <aksenzov@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Doesn't work Atheros AR8131 PCIe Gigabit Ethernet
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         149306
>Category:       kern
>Synopsis:       [alc] Doesn't work Atheros AR8131 PCIe Gigabit Ethernet
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    jhb
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Aug 05 04:50:06 UTC 2010
>Closed-Date:    Thu Jul 07 18:58:08 UTC 2011
>Last-Modified:  Thu Jul 07 18:58:08 UTC 2011
>Originator:     KsenZ
>Release:        8.1
>Organization:
>Environment:
>Description:
alc0: <Atheros AR8131 PCIe Gigabit Ethernet> irq 17 at device 0.0 on pci9
alc0: 0x40000 bytes of rid 0x10 res 3 failed (0, 0xffffffff).
alc0: cannot allocate memory resources.
device_attach: alc0 attach returned 6
>How-To-Repeat:

>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Aug 5 08:05:13 UTC 2010 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=149306 

From: Troye Johnson <drsweetlips@gmail.com>
To: bug-followup@FreeBSD.org, aksenzov@gmail.com
Cc:  
Subject: Re: kern/149306: [alc] Doesn't work Atheros AR8131 PCIe Gigabit 
	Ethernet
Date: Thu, 5 Aug 2010 17:16:07 +0000

 --000e0cd51986b1efd9048d16b405
 Content-Type: text/plain; charset=ISO-8859-1
 
 I think this is misfiled as I have this chip and it is detected properly and
 and I can transfer files over the link in 100mbit. Misfiled/erroneous PR?
 
 --000e0cd51986b1efd9048d16b405
 Content-Type: text/html; charset=ISO-8859-1
 
 I think this is misfiled as I have this chip and it is detected properly and and I can transfer files over the link in 100mbit. Misfiled/erroneous PR?<br>
 
 --000e0cd51986b1efd9048d16b405--

From: =?iso-8859-1?Q?Ren=E9?= Rietz <rrietz@Informatik.tu-Cottbus.DE>
To: bug-followup@FreeBSD.org, aksenzov@gmail.com
Cc:  
Subject: Re: kern/149306: [alc] Doesn't work Atheros AR8131 PCIe Gigabit
 Ethernet
Date: Wed, 1 Sep 2010 09:42:26 +0200

 --cNdxnHkX5QqsyA0e
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 Can someone assign this bug to acpi? According to the driver developer, this
 seems to be an acpi problem:
 http://forums.freebsd.org/showthread.php?t=16186
 
 Bug #149373 seems to be related to the same problem.
 
 
 --cNdxnHkX5QqsyA0e
 Content-Type: application/x-pkcs7-signature
 Content-Disposition: attachment; filename="smime.p7s"
 Content-Transfer-Encoding: base64
 
 MIISqwYJKoZIhvcNAQcCoIISnDCCEpgCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
 D54wggVaMIIEQqADAgECAgQLie+tMA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNVBAYTAkRFMRMw
 EQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVy
 ZWluIFBDQSBHbG9iYWwgLSBHMDEwHhcNMDcxMjIwMTM0NjA2WhcNMTkwNjMwMDAwMDAwWjCB
 yTELMAkGA1UEBhMCREUxFDASBgNVBAgTC0JyYW5kZW5idXJnMRAwDgYDVQQHEwdDb3R0YnVz
 MTkwNwYDVQQKEzBCcmFuZGVuYnVyZ2lzY2hlIFRlY2huaXNjaGUgVW5pdmVyc2l0YWV0IENv
 dHRidXMxFjAUBgNVBAsTDVJlY2hlbnplbnRydW0xGjAYBgNVBAMTEUJUVS1DQSAoRzAxIDIw
 MDgpMSMwIQYJKoZIhvcNAQkBFhRjYS1idHVAdHUtY290dGJ1cy5kZTCCASIwDQYJKoZIhvcN
 AQEBBQADggEPADCCAQoCggEBALtCHiiZ9xL7pJCDfykBz8QUFPqPvdQoFG2fh+NsvIEId6vz
 adydM95kVniA/dkAfUW4sMGCb8wElKPihwJQ2R+SdMf4dL2vQBnwyT+hasrBYRaVj6sGgUKD
 8yxxdF7UkY4WWeVjg03I4HCeFjiRWLfeDPY98mXko9NqguOIP00tbU7HCwbJ9cckLt6fds8J
 dKeyxrSFvNFVc5xwZlaGGYGcw/sqLGXeOoaISA/5Anb/pg7uWdpxtjzkChGhVTkSHTZ0DIBv
 lV5BvmiO5xA/oDvOoGz9bz/vuBUMDVNzZZy4EQFDDlSKAg+/+ptur8r4WfoIlohWL2UVyjO7
 jdY4bsMCAwEAAaOCAbYwggGyMBIGA1UdEwEB/wQIMAYBAf8CAQEwCwYDVR0PBAQDAgEGMB0G
 A1UdDgQWBBRYHbJqrZIxc6XbOTlSZxpEBto+FjAfBgNVHSMEGDAWgBRJt8bP6D0ff+pEexMp
 9/EKcD7eZDAfBgNVHREEGDAWgRRjYS1idHVAdHUtY290dGJ1cy5kZTCBiAYDVR0fBIGAMH4w
 PaA7oDmGN2h0dHA6Ly9jZHAxLnBjYS5kZm4uZGUvZ2xvYmFsLXJvb3QtY2EvcHViL2NybC9j
 YWNybC5jcmwwPaA7oDmGN2h0dHA6Ly9jZHAyLnBjYS5kZm4uZGUvZ2xvYmFsLXJvb3QtY2Ev
 cHViL2NybC9jYWNybC5jcmwwgaIGCCsGAQUFBwEBBIGVMIGSMEcGCCsGAQUFBzAChjtodHRw
 Oi8vY2RwMS5wY2EuZGZuLmRlL2dsb2JhbC1yb290LWNhL3B1Yi9jYWNlcnQvY2FjZXJ0LmNy
 dDBHBggrBgEFBQcwAoY7aHR0cDovL2NkcDIucGNhLmRmbi5kZS9nbG9iYWwtcm9vdC1jYS9w
 dWIvY2FjZXJ0L2NhY2VydC5jcnQwDQYJKoZIhvcNAQEFBQADggEBAA1vZXHoiKaPyfy0JY7Z
 s5HgWS2ecQSmBoNaHR3vfMXJai8RbU9+a31bP8RuimTZ/hvv57bj49qopAeby6NClDVJWE3O
 SAOEZgG0x3sYfObJyuV+SZs0oOoXqyTJHpGRqrBVpUHIB3xUKzT0o3A+BDSyhxY6JJjef2q0
 KX9Lbcw6j9SA/xv/IRCEAtUjTGEJCUTxJroVy7TIvV7G7TrCtw8MwIQClL8UMsD9iXvYfISE
 aJDmWLFlv0hLG0XdTLFxLiXDelx3oVhg4CQhguksupmdWx2twMSlQmMOFk/u69FFQ/tbXeSq
 5oA8pam1Pf3DoODxtYZ/wnb6BFyCgOza4mwwggQhMIIDCaADAgECAgIAxzANBgkqhkiG9w0B
 AQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G
 A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtv
 bSBSb290IENBIDIwHhcNMDYxMjE5MTAyOTAwWhcNMTkwNjMwMjM1OTAwWjBaMQswCQYDVQQG
 EwJERTETMBEGA1UEChMKREZOLVZlcmVpbjEQMA4GA1UECxMHREZOLVBLSTEkMCIGA1UEAxMb
 REZOLVZlcmVpbiBQQ0EgR2xvYmFsIC0gRzAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
 CgKCAQEA6ZvDZ4X5Da71jVTDllA1PWLpbkztlNcAW5UidNQg6zSP1uzAMQQLmYHiphTSUqAo
 I4SLdIkEXlvg4njBeMsWyyg1OXstkEXQ7aAAeny/Sg4bAMOG6VwrMRF7DPOCJEOMHDiLamgA
 mu7cT3ir0sYTm3at7t4m6O8Br3QPwQmi9mvOvdPNFDBP9eXjpMhim4IaAycwDQJlYE3t0Qkj
 KpY1WCfTdsZxtpAdxO3/NYZ9bzOz2w/FEcKKg6GUXUFr2NIQ9Uz9ylGs2b3vkoO72uuLFlZW
 Q8/h1RM9ph8nMM1JVNvJEzSacXXFbOqnC5j5IZ0nrz6jOTlIaoytyZn7wxLyvQIDAQABo4HZ
 MIHWMHAGA1UdHwRpMGcwZaBjoGGGX2h0dHA6Ly9wa2kudGVsZXNlYy5kZS9jZ2ktYmluL3Nl
 cnZpY2UvYWZfRG93bmxvYWRBUkwuY3JsPy1jcmxfZm9ybWF0PVhfNTA5Ji1pc3N1ZXI9RFRf
 Uk9PVF9DQV8yMB0GA1UdDgQWBBRJt8bP6D0ff+pEexMp9/EKcD7eZDAfBgNVHSMEGDAWgBQx
 w3kbuvVT1xfgiXotF2wKsyudMzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIB
 AjANBgkqhkiG9w0BAQUFAAOCAQEAO+Fad8BIF9ypGOyBr1qJ8L0okqbKWRgScOwo8ueuf5Ys
 5/JdGTH2Eyt0vb2Asrn3Z8k5onk74RER7mt4kTN+O18mJ3VTZY4zY+7Pc8OwkiNJIVB1I6Ef
 GOKUhT0/M+l3II2iveahhSlA9j9zMlgNCWum2oVswD+7jWZkViROrg0/MjUBW+mMgtlyWU+x
 hoXxdIVW5cP4XPON7kezUwVw5+VNimmDKOETCYaeXsjqWB4MH/mk1FoEaP0oPosCtli19qEs
 N1cAZ6sjaI1jpe+Za1z9S1b2q0CHNNQRkmzsh8UKCwczcrRvDB1ULNhRx8y/MNNDcvEyv4zO
 SWOoAPfyHDCCBhcwggT/oAMCAQICBA7S9T0wDQYJKoZIhvcNAQEFBQAwgckxCzAJBgNVBAYT
 AkRFMRQwEgYDVQQIEwtCcmFuZGVuYnVyZzEQMA4GA1UEBxMHQ290dGJ1czE5MDcGA1UEChMw
 QnJhbmRlbmJ1cmdpc2NoZSBUZWNobmlzY2hlIFVuaXZlcnNpdGFldCBDb3R0YnVzMRYwFAYD
 VQQLEw1SZWNoZW56ZW50cnVtMRowGAYDVQQDExFCVFUtQ0EgKEcwMSAyMDA4KTEjMCEGCSqG
 SIb3DQEJARYUY2EtYnR1QHR1LWNvdHRidXMuZGUwHhcNMDkwOTE4MTIwNjA2WhcNMTIwOTE3
 MTIwNjA2WjCB6TELMAkGA1UEBhMCREUxFDASBgNVBAgTC0JyYW5kZW5idXJnMRAwDgYDVQQH
 EwdDb3R0YnVzMTkwNwYDVQQKEzBCcmFuZGVuYnVyZ2lzY2hlIFRlY2huaXNjaGUgVW5pdmVy
 c2l0YWV0IENvdHRidXMxMjAwBgNVBAsTKUxTIFJlY2huZXJuZXR6ZSB1bmQgS29tbXVuaWth
 dGlvbnNzeXN0ZW1lMRMwEQYDVQQDEwpSZW5lIFJpZXR6MS4wLAYJKoZIhvcNAQkBFh9ycmll
 dHpAaW5mb3JtYXRpay50dS1jb3R0YnVzLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
 CgKCAQEA3gSr5iaJtuQeJoO31OekQDDptiI5pWBl3UQw719nJ6peDbqofyKxINmy+H+4Da4Z
 4/UqG6JSmWQEQtttI6vCzQrkho76a3bp4sXMTCA7Ow8ImBB0tS2J9VzDoK1qsYsm+HjI/Edx
 4SsDTVhYUsZhq3Lqx6UHgYs7evFq5HoQpS7NuA4aj3B4T968FV9pW3QtyA4sZUqmFIEmhP6+
 eoqXspr5ON8hKLcWGNd21xJU4zXdSULVTt65YCFnvPwrS5RPxgGtIUwO3qaOjBOI6/lmpOiH
 hqtk08p+qKqmqMVjK7NyF/5i0WHQrBJ4NcNK3GujlQxJ2nPInI2O06cDIgJi5wIDAQABo4IB
 4zCCAd8wCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwKQYDVR0lBCIwIAYIKwYBBQUHAwIGCCsG
 AQUFBwMEBgorBgEEAYI3FAICMB0GA1UdDgQWBBTIRRXeq9ijqEh6KjV19tuezDG42DAfBgNV
 HSMEGDAWgBRYHbJqrZIxc6XbOTlSZxpEBto+FjAqBgNVHREEIzAhgR9ycmlldHpAaW5mb3Jt
 YXRpay50dS1jb3R0YnVzLmRlMIGIBgNVHR8EgYAwfjA9oDugOYY3aHR0cDovL2NkcDEucGNh
 LmRmbi5kZS9idHUtY290dGJ1cy1jYS9wdWIvY3JsL2NhY3JsLmNybDA9oDugOYY3aHR0cDov
 L2NkcDIucGNhLmRmbi5kZS9idHUtY290dGJ1cy1jYS9wdWIvY3JsL2NhY3JsLmNybDCBogYI
 KwYBBQUHAQEEgZUwgZIwRwYIKwYBBQUHMAKGO2h0dHA6Ly9jZHAxLnBjYS5kZm4uZGUvYnR1
 LWNvdHRidXMtY2EvcHViL2NhY2VydC9jYWNlcnQuY3J0MEcGCCsGAQUFBzAChjtodHRwOi8v
 Y2RwMi5wY2EuZGZuLmRlL2J0dS1jb3R0YnVzLWNhL3B1Yi9jYWNlcnQvY2FjZXJ0LmNydDAN
 BgkqhkiG9w0BAQUFAAOCAQEAGsmRTRyyQLUBeVaEp5CrS2qiZECrQG1UrkfVtznDf4l5FQKw
 hA7KhPBdLEW/wamvlQS3Zg18OcZZ4+IYHQPdQrEurXLcCYEQn1tt1Sj8iQh+4QqhiY7ppKLg
 Amy1txMhnw0KgiTOs4dpyx9ANbS4rTpA1qGsit5cjRA5CwcAhqvBDZp6XbfpQ9OBU0p292c2
 pJufZvcEUf1Qm7krgZURZwOoAvH+1CmN+mYg6XqoD7K74/FsBSAbeT63lr2jgGb3Ac6C9kLz
 z2aJz7BYJU+xbjyfk5LXsCIfAz4VXE5f2ndq6qPtD5XknssrGzM8UCmZEkkhCLIzlgqq645P
 hxyKqDGCAtUwggLRAgEBMIHSMIHJMQswCQYDVQQGEwJERTEUMBIGA1UECBMLQnJhbmRlbmJ1
 cmcxEDAOBgNVBAcTB0NvdHRidXMxOTA3BgNVBAoTMEJyYW5kZW5idXJnaXNjaGUgVGVjaG5p
 c2NoZSBVbml2ZXJzaXRhZXQgQ290dGJ1czEWMBQGA1UECxMNUmVjaGVuemVudHJ1bTEaMBgG
 A1UEAxMRQlRVLUNBIChHMDEgMjAwOCkxIzAhBgkqhkiG9w0BCQEWFGNhLWJ0dUB0dS1jb3R0
 YnVzLmRlAgQO0vU9MAkGBSsOAwIaBQCggdgwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc
 BgkqhkiG9w0BCQUxDxcNMTAwOTAxMDc0MjI2WjAjBgkqhkiG9w0BCQQxFgQUlS9bjZETvf0a
 KAozF6QOGkSzCJUweQYJKoZIhvcNAQkPMWwwajALBglghkgBZQMEASowCwYJYIZIAWUDBAEW
 MAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwIC
 AUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwDQYJKoZIhvcNAQEBBQAEggEAtTeYOooE89CN
 4mp6fGR7ksD9KKAafrbMwjuuwkz/bDbYan3Pv97Fyn9C1sT7xkBti6cLeGLlKqsj2mjwBzz7
 7Zx4Su3BPt7a1np6MKomYba/WUEs0XuvkYxj9P5WfLtryZ+8H6pTGZPmNIppnjMJ3CqzaLF8
 WdUlrXc5+tbIQK8nHx1MG4r2MQYScKsgDgDBEjzJgQGYKNC2Wu6L/vGR8GfAfPtI95f6+NLA
 Xk20VyYmCKXQEm7KETIRkct+sLW/BRdhuq0+PgwEsg9Tq3t/2E8liPRlybDhms1RzIQ+BpVo
 vTByotJtRqu4OhvVQKB4Smx123nelEXkCrr64fVpKQ==
 
 --cNdxnHkX5QqsyA0e--

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/149306: commit references a PR
Date: Tue,  3 May 2011 17:37:34 +0000 (UTC)

 Author: jhb
 Date: Tue May  3 17:37:24 2011
 New Revision: 221393
 URL: http://svn.freebsd.org/changeset/base/221393
 
 Log:
   Reimplement how PCI-PCI bridges manage their I/O windows.  Previously the
   driver would verify that requests for child devices were confined to any
   existing I/O windows, but the driver relied on the firmware to initialize
   the windows and would never grow the windows for new requests.  Now the
   driver actively manages the I/O windows.
   
   This is implemented by allocating a bus resource for each I/O window from
   the parent PCI bus and suballocating that resource to child devices.  The
   suballocations are managed by creating an rman for each I/O window.  The
   suballocated resources are mapped by passing the bus_activate_resource()
   call up to the parent PCI bus.  Windows are grown when needed by using
   bus_adjust_resource() to adjust the resource allocated from the parent PCI
   bus.  If the adjust request succeeds, the window is adjusted and the
   suballocation request for the child device is retried.
   
   When growing a window, the rman_first_free_region() and
   rman_last_free_region() routines are used to determine if the front or
   end of the existing I/O window is free.  From using that, the smallest
   ranges that need to be added to either the front or back of the window
   are computed.  The driver will first try to grow the window in whichever
   direction requires the smallest growth first followed by the other
   direction if that fails.
   
   Subtractive bridges will first attempt to satisfy requests for child
   resources from I/O windows (including attempts to grow the windows).  If
   that fails, the request is passed up to the parent PCI bus directly
   however.
   
   The PCI-PCI bridge driver will try to use firmware-assigned ranges for
   child BARs first and only allocate a "fresh" range if that specific range
   cannot be accommodated in the I/O window.  This allows systems where the
   firmware assigns resources during boot but later wipes the I/O windows
   (some ACPI BIOSen are known to do this) to "rediscover" the original I/O
   window ranges.
   
   The ACPI Host-PCI bridge driver has been adjusted to correctly honor
   hw.acpi.host_mem_start and the I/O port equivalent when a PCI-PCI bridge
   makes a wildcard request for an I/O window range.
   
   The new PCI-PCI bridge driver is only enabled if the NEW_PCIB kernel option
   is enabled.  This is a transition aide to allow platforms that do not
   yet support bus_activate_resource() and bus_adjust_resource() in their
   Host-PCI bridge drivers (and possibly other drivers as needed) to use the
   old driver for now.  Once all platforms support the new driver, the
   kernel option and old driver will be removed.
   
   PR:		kern/143874 kern/149306
   Tested by:	mav
 
 Modified:
   head/sys/amd64/pci/pci_bus.c
   head/sys/conf/options
   head/sys/dev/acpica/acpi_pcib_acpi.c
   head/sys/dev/acpica/acpi_pcib_pci.c
   head/sys/dev/pci/pci.c
   head/sys/dev/pci/pci_pci.c
   head/sys/dev/pci/pcib_private.h
   head/sys/i386/pci/pci_bus.c
   head/sys/sparc64/pci/apb.c
   head/sys/sparc64/pci/ofw_pcib.c
   head/sys/x86/pci/qpi.c
   head/sys/x86/x86/mptable_pci.c
 
 Modified: head/sys/amd64/pci/pci_bus.c
 ==============================================================================
 --- head/sys/amd64/pci/pci_bus.c	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/amd64/pci/pci_bus.c	Tue May  3 17:37:24 2011	(r221393)
 @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/kernel.h>
  #include <sys/malloc.h>
  #include <sys/module.h>
 +#include <sys/rman.h>
  #include <sys/sysctl.h>
  
  #include <dev/pci/pcivar.h>
 
 Modified: head/sys/conf/options
 ==============================================================================
 --- head/sys/conf/options	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/conf/options	Tue May  3 17:37:24 2011	(r221393)
 @@ -136,6 +136,7 @@ MFI_DEBUG	opt_mfi.h
  MFI_DECODE_LOG	opt_mfi.h
  MPROF_BUFFERS	opt_mprof.h
  MPROF_HASH_SIZE	opt_mprof.h
 +NEW_PCIB	opt_global.h
  NO_ADAPTIVE_MUTEXES	opt_adaptive_mutexes.h
  NO_ADAPTIVE_RWLOCKS
  NO_ADAPTIVE_SX
 
 Modified: head/sys/dev/acpica/acpi_pcib_acpi.c
 ==============================================================================
 --- head/sys/dev/acpica/acpi_pcib_acpi.c	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/dev/acpica/acpi_pcib_acpi.c	Tue May  3 17:37:24 2011	(r221393)
 @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/kernel.h>
  #include <sys/malloc.h>
  #include <sys/module.h>
 +#include <sys/rman.h>
  #include <sys/sysctl.h>
  
  #include <contrib/dev/acpica/include/acpi.h>
 @@ -370,11 +371,17 @@ acpi_pcib_acpi_alloc_resource(device_t d
       * Hardcoding like this sucks, so a more MD/MI way needs to be
       * found to do it.  This is typically only used on older laptops
       * that don't have pci busses behind pci bridge, so assuming > 32MB
 -     * is liekly OK.
 +     * is likely OK.
 +     *
 +     * PCI-PCI bridges may allocate smaller ranges for their windows,
 +     * but the heuristics here should apply to those, so we allow
 +     * several different end addresses.
       */
 -    if (type == SYS_RES_MEMORY && start == 0UL && end == ~0UL)
 +    if (type == SYS_RES_MEMORY && start == 0UL && (end == ~0UL ||
 +	end == 0xffffffff))
  	start = acpi_host_mem_start;
 -    if (type == SYS_RES_IOPORT && start == 0UL && end == ~0UL)
 +    if (type == SYS_RES_IOPORT && start == 0UL && (end == ~0UL ||
 +	end == 0xffff || end == 0xffffffff))
  	start = 0x1000;
      return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
  	count, flags));
 
 Modified: head/sys/dev/acpica/acpi_pcib_pci.c
 ==============================================================================
 --- head/sys/dev/acpica/acpi_pcib_pci.c	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/dev/acpica/acpi_pcib_pci.c	Tue May  3 17:37:24 2011	(r221393)
 @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/kernel.h>
  #include <sys/malloc.h>
  #include <sys/module.h>
 +#include <sys/rman.h>
  
  #include <contrib/dev/acpica/include/acpi.h>
  #include <contrib/dev/acpica/include/accommon.h>
 
 Modified: head/sys/dev/pci/pci.c
 ==============================================================================
 --- head/sys/dev/pci/pci.c	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/dev/pci/pci.c	Tue May  3 17:37:24 2011	(r221393)
 @@ -3967,6 +3967,26 @@ pci_alloc_resource(device_t dev, device_
  		break;
  	case SYS_RES_IOPORT:
  	case SYS_RES_MEMORY:
 +#ifdef NEW_PCIB
 +		/*
 +		 * PCI-PCI bridge I/O window resources are not BARs.
 +		 * For those allocations just pass the request up the
 +		 * tree.
 +		 */
 +		if (cfg->hdrtype == PCIM_HDRTYPE_BRIDGE) {
 +			switch (*rid) {
 +			case PCIR_IOBASEL_1:
 +			case PCIR_MEMBASE_1:
 +			case PCIR_PMBASEL_1:
 +				/*
 +				 * XXX: Should we bother creating a resource
 +				 * list entry?
 +				 */
 +				return (bus_generic_alloc_resource(dev, child,
 +				    type, rid, start, end, count, flags));
 +			}
 +		}
 +#endif
  		/* Reserve resources for this BAR if needed. */
  		rle = resource_list_find(rl, type, *rid);
  		if (rle == NULL) {
 
 Modified: head/sys/dev/pci/pci_pci.c
 ==============================================================================
 --- head/sys/dev/pci/pci_pci.c	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/dev/pci/pci_pci.c	Tue May  3 17:37:24 2011	(r221393)
 @@ -36,14 +36,16 @@ __FBSDID("$FreeBSD$");
   */
  
  #include <sys/param.h>
 -#include <sys/systm.h>
 +#include <sys/bus.h>
  #include <sys/kernel.h>
 +#include <sys/libkern.h>
 +#include <sys/malloc.h>
  #include <sys/module.h>
 -#include <sys/bus.h>
 -#include <machine/bus.h>
  #include <sys/rman.h>
  #include <sys/sysctl.h>
 +#include <sys/systm.h>
  
 +#include <machine/bus.h>
  #include <machine/resource.h>
  
  #include <dev/pci/pcivar.h>
 @@ -73,8 +75,13 @@ static device_method_t pcib_methods[] = 
      DEVMETHOD(bus_read_ivar,		pcib_read_ivar),
      DEVMETHOD(bus_write_ivar,		pcib_write_ivar),
      DEVMETHOD(bus_alloc_resource,	pcib_alloc_resource),
 +#ifdef NEW_PCIB
 +    DEVMETHOD(bus_adjust_resource,	pcib_adjust_resource),
 +    DEVMETHOD(bus_release_resource,	pcib_release_resource),
 +#else
      DEVMETHOD(bus_adjust_resource,	bus_generic_adjust_resource),
      DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
 +#endif
      DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
      DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
      DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
 @@ -100,6 +107,243 @@ static devclass_t pcib_devclass;
  DEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc));
  DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, 0, 0);
  
 +#ifdef NEW_PCIB
 +/*
 + * XXX Todo:
 + * - properly handle the ISA enable bit.  If it is set, we should change
 + *   the behavior of the I/O window resource and rman to not allocate the
 + *   blocked ranges (upper 768 bytes of each 1K in the first 64k of the
 + *   I/O port address space).
 + */
 +
 +/*
 + * Is a resource from a child device sub-allocated from one of our
 + * resource managers?
 + */
 +static int
 +pcib_is_resource_managed(struct pcib_softc *sc, int type, struct resource *r)
 +{
 +
 +	switch (type) {
 +	case SYS_RES_IOPORT:
 +		return (rman_is_region_manager(r, &sc->io.rman));
 +	case SYS_RES_MEMORY:
 +		/* Prefetchable resources may live in either memory rman. */
 +		if (rman_get_flags(r) & RF_PREFETCHABLE &&
 +		    rman_is_region_manager(r, &sc->pmem.rman))
 +			return (1);
 +		return (rman_is_region_manager(r, &sc->mem.rman));
 +	}
 +	return (0);
 +}
 +
 +static int
 +pcib_is_window_open(struct pcib_window *pw)
 +{
 +
 +	return (pw->valid && pw->base < pw->limit);
 +}
 +
 +/*
 + * XXX: If RF_ACTIVE did not also imply allocating a bus space tag and
 + * handle for the resource, we could pass RF_ACTIVE up to the PCI bus
 + * when allocating the resource windows and rely on the PCI bus driver
 + * to do this for us.
 + */
 +static void
 +pcib_activate_window(struct pcib_softc *sc, int type)
 +{
 +
 +	PCI_ENABLE_IO(device_get_parent(sc->dev), sc->dev, type);
 +}
 +
 +static void
 +pcib_write_windows(struct pcib_softc *sc, int mask)
 +{
 +	device_t dev;
 +	uint32_t val;
 +
 +	dev = sc->dev;
 +	if (sc->io.valid && mask & WIN_IO) {
 +		val = pci_read_config(dev, PCIR_IOBASEL_1, 1);
 +		if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) {
 +			pci_write_config(dev, PCIR_IOBASEH_1,
 +			    sc->io.base >> 16, 2);
 +			pci_write_config(dev, PCIR_IOLIMITH_1,
 +			    sc->io.limit >> 16, 2);
 +		}
 +		pci_write_config(dev, PCIR_IOBASEL_1, sc->io.base >> 8, 1);
 +		pci_write_config(dev, PCIR_IOLIMITL_1, sc->io.limit >> 8, 1);
 +	}
 +
 +	if (mask & WIN_MEM) {
 +		pci_write_config(dev, PCIR_MEMBASE_1, sc->mem.base >> 16, 2);
 +		pci_write_config(dev, PCIR_MEMLIMIT_1, sc->mem.limit >> 16, 2);
 +	}
 +
 +	if (sc->pmem.valid && mask & WIN_PMEM) {
 +		val = pci_read_config(dev, PCIR_PMBASEL_1, 2);
 +		if ((val & PCIM_BRPM_MASK) == PCIM_BRPM_64) {
 +			pci_write_config(dev, PCIR_PMBASEH_1,
 +			    sc->pmem.base >> 32, 4);
 +			pci_write_config(dev, PCIR_PMLIMITH_1,
 +			    sc->pmem.limit >> 32, 4);
 +		}
 +		pci_write_config(dev, PCIR_PMBASEL_1, sc->pmem.base >> 16, 2);
 +		pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmem.limit >> 16, 2);
 +	}
 +}
 +
 +static void
 +pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 +    int flags, pci_addr_t max_address)
 +{
 +	char buf[64];
 +	int error, rid;
 +
 +	if (max_address != (u_long)max_address)
 +		max_address = ~0ul;
 +	w->rman.rm_start = 0;
 +	w->rman.rm_end = max_address;
 +	w->rman.rm_type = RMAN_ARRAY;
 +	snprintf(buf, sizeof(buf), "%s %s window",
 +	    device_get_nameunit(sc->dev), w->name);
 +	w->rman.rm_descr = strdup(buf, M_DEVBUF);
 +	error = rman_init(&w->rman);
 +	if (error)
 +		panic("Failed to initialize %s %s rman",
 +		    device_get_nameunit(sc->dev), w->name);
 +
 +	if (!pcib_is_window_open(w))
 +		return;
 +
 +	if (w->base > max_address || w->limit > max_address) {
 +		device_printf(sc->dev,
 +		    "initial %s window has too many bits, ignoring\n", w->name);
 +		return;
 +	}
 +	rid = w->reg;
 +	w->res = bus_alloc_resource(sc->dev, type, &rid, w->base, w->limit,
 +	    w->limit - w->base + 1, flags);
 +	if (w->res == NULL) {
 +		device_printf(sc->dev,
 +		    "failed to allocate initial %s window: %#jx-%#jx\n",
 +		    w->name, (uintmax_t)w->base, (uintmax_t)w->limit);
 +		w->base = max_address;
 +		w->limit = 0;
 +		pcib_write_windows(sc, w->mask);
 +		return;
 +	}
 +	pcib_activate_window(sc, type);
 +
 +	error = rman_manage_region(&w->rman, rman_get_start(w->res),
 +	    rman_get_end(w->res));
 +	if (error)
 +		panic("Failed to initialize rman with resource");
 +}
 +
 +/*
 + * Initialize I/O windows.
 + */
 +static void
 +pcib_probe_windows(struct pcib_softc *sc)
 +{
 +	pci_addr_t max;
 +	device_t dev;
 +	uint32_t val;
 +
 +	dev = sc->dev;
 +
 +	/* Determine if the I/O port window is implemented. */
 +	val = pci_read_config(dev, PCIR_IOBASEL_1, 1);
 +	if (val == 0) {
 +		/*
 +		 * If 'val' is zero, then only 16-bits of I/O space
 +		 * are supported.
 +		 */
 +		pci_write_config(dev, PCIR_IOBASEL_1, 0xff, 1);
 +		if (pci_read_config(dev, PCIR_IOBASEL_1, 1) != 0) {
 +			sc->io.valid = 1;
 +			pci_write_config(dev, PCIR_IOBASEL_1, 0, 1);
 +		}
 +	} else
 +		sc->io.valid = 1;
 +
 +	/* Read the existing I/O port window. */
 +	if (sc->io.valid) {
 +		sc->io.reg = PCIR_IOBASEL_1;
 +		sc->io.step = 12;
 +		sc->io.mask = WIN_IO;
 +		sc->io.name = "I/O port";
 +		if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) {
 +			sc->io.base = PCI_PPBIOBASE(
 +			    pci_read_config(dev, PCIR_IOBASEH_1, 2), val);
 +			sc->io.limit = PCI_PPBIOLIMIT(
 +			    pci_read_config(dev, PCIR_IOLIMITH_1, 2),
 +			    pci_read_config(dev, PCIR_IOLIMITL_1, 1));
 +			max = 0xffffffff;
 +		} else {
 +			sc->io.base = PCI_PPBIOBASE(0, val);
 +			sc->io.limit = PCI_PPBIOLIMIT(0,
 +			    pci_read_config(dev, PCIR_IOLIMITL_1, 1));
 +			max = 0xffff;
 +		}
 +		pcib_alloc_window(sc, &sc->io, SYS_RES_IOPORT, 0, max);
 +	}
 +
 +	/* Read the existing memory window. */
 +	sc->mem.valid = 1;
 +	sc->mem.reg = PCIR_MEMBASE_1;
 +	sc->mem.step = 20;
 +	sc->mem.mask = WIN_MEM;
 +	sc->mem.name = "memory";
 +	sc->mem.base = PCI_PPBMEMBASE(0,
 +	    pci_read_config(dev, PCIR_MEMBASE_1, 2));
 +	sc->mem.limit = PCI_PPBMEMLIMIT(0,
 +	    pci_read_config(dev, PCIR_MEMLIMIT_1, 2));
 +	pcib_alloc_window(sc, &sc->mem, SYS_RES_MEMORY, 0, 0xffffffff);
 +
 +	/* Determine if the prefetchable memory window is implemented. */
 +	val = pci_read_config(dev, PCIR_PMBASEL_1, 2);
 +	if (val == 0) {
 +		/*
 +		 * If 'val' is zero, then only 32-bits of memory space
 +		 * are supported.
 +		 */
 +		pci_write_config(dev, PCIR_PMBASEL_1, 0xffff, 2);
 +		if (pci_read_config(dev, PCIR_PMBASEL_1, 2) != 0) {
 +			sc->pmem.valid = 1;
 +			pci_write_config(dev, PCIR_PMBASEL_1, 0, 2);
 +		}
 +	} else
 +		sc->pmem.valid = 1;
 +
 +	/* Read the existing prefetchable memory window. */
 +	if (sc->pmem.valid) {
 +		sc->pmem.reg = PCIR_PMBASEL_1;
 +		sc->pmem.step = 20;
 +		sc->pmem.mask = WIN_PMEM;
 +		sc->pmem.name = "prefetch";
 +		if ((val & PCIM_BRPM_MASK) == PCIM_BRPM_64) {
 +			sc->pmem.base = PCI_PPBMEMBASE(
 +			    pci_read_config(dev, PCIR_PMBASEH_1, 4), val);
 +			sc->pmem.limit = PCI_PPBMEMLIMIT(
 +			    pci_read_config(dev, PCIR_PMLIMITH_1, 4),
 +			    pci_read_config(dev, PCIR_PMLIMITL_1, 2));
 +			max = 0xffffffffffffffff;
 +		} else {
 +			sc->pmem.base = PCI_PPBMEMBASE(0, val);
 +			sc->pmem.limit = PCI_PPBMEMLIMIT(0,
 +			    pci_read_config(dev, PCIR_PMLIMITL_1, 2));
 +			max = 0xffffffff;
 +		}
 +		pcib_alloc_window(sc, &sc->pmem, SYS_RES_MEMORY,
 +		    RF_PREFETCHABLE, max);
 +	}
 +}
 +
 +#else
 +
  /*
   * Is the prefetch window open (eg, can we allocate memory in it?)
   */
 @@ -230,6 +474,7 @@ pcib_set_mem_decode(struct pcib_softc *s
  		pci_write_config(dev, PCIR_PMLIMITH_1, pmemhi, 4);
  	pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmemlimit >> 16, 2);
  }
 +#endif
  
  /*
   * Get current bridge configuration.
 @@ -247,10 +492,12 @@ pcib_cfg_save(struct pcib_softc *sc)
  	sc->subbus = pci_read_config(dev, PCIR_SUBBUS_1, 1);
  	sc->bridgectl = pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
  	sc->seclat = pci_read_config(dev, PCIR_SECLAT_1, 1);
 +#ifndef NEW_PCIB
  	if (sc->command & PCIM_CMD_PORTEN)
  		pcib_get_io_decode(sc);
  	if (sc->command & PCIM_CMD_MEMEN)
  		pcib_get_mem_decode(sc);
 +#endif
  }
  
  /*
 @@ -269,10 +516,14 @@ pcib_cfg_restore(struct pcib_softc *sc)
  	pci_write_config(dev, PCIR_SUBBUS_1, sc->subbus, 1);
  	pci_write_config(dev, PCIR_BRIDGECTL_1, sc->bridgectl, 2);
  	pci_write_config(dev, PCIR_SECLAT_1, sc->seclat, 1);
 +#ifdef NEW_PCIB
 +	pcib_write_windows(sc, WIN_IO | WIN_MEM | WIN_PMEM);
 +#else
  	if (sc->command & PCIM_CMD_PORTEN)
  		pcib_set_io_decode(sc);
  	if (sc->command & PCIM_CMD_MEMEN)
  		pcib_set_mem_decode(sc);
 +#endif
  }
  
  /*
 @@ -389,18 +640,35 @@ pcib_attach_common(device_t dev)
      if ((pci_get_devid(dev) & 0xff00ffff) == 0x24008086 ||
        pci_read_config(dev, PCIR_PROGIF, 1) == PCIP_BRIDGE_PCI_SUBTRACTIVE)
  	sc->flags |= PCIB_SUBTRACTIVE;
 -	
 +
 +#ifdef NEW_PCIB
 +    pcib_probe_windows(sc);
 +#endif
      if (bootverbose) {
  	device_printf(dev, "  domain            %d\n", sc->domain);
  	device_printf(dev, "  secondary bus     %d\n", sc->secbus);
  	device_printf(dev, "  subordinate bus   %d\n", sc->subbus);
 -	device_printf(dev, "  I/O decode        0x%x-0x%x\n", sc->iobase, sc->iolimit);
 +#ifdef NEW_PCIB
 +	if (pcib_is_window_open(&sc->io))
 +	    device_printf(dev, "  I/O decode        0x%jx-0x%jx\n",
 +	      (uintmax_t)sc->io.base, (uintmax_t)sc->io.limit);
 +	if (pcib_is_window_open(&sc->mem))
 +	    device_printf(dev, "  memory decode     0x%jx-0x%jx\n",
 +	      (uintmax_t)sc->mem.base, (uintmax_t)sc->mem.limit);
 +	if (pcib_is_window_open(&sc->pmem))
 +	    device_printf(dev, "  prefetched decode 0x%jx-0x%jx\n",
 +	      (uintmax_t)sc->pmem.base, (uintmax_t)sc->pmem.limit);
 +#else
 +	if (pcib_is_io_open(sc))
 +	    device_printf(dev, "  I/O decode        0x%x-0x%x\n",
 +	      sc->iobase, sc->iolimit);
  	if (pcib_is_nonprefetch_open(sc))
  	    device_printf(dev, "  memory decode     0x%jx-0x%jx\n",
  	      (uintmax_t)sc->membase, (uintmax_t)sc->memlimit);
  	if (pcib_is_prefetch_open(sc))
  	    device_printf(dev, "  prefetched decode 0x%jx-0x%jx\n",
  	      (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit);
 +#endif
  	else
  	    device_printf(dev, "  no prefetched decode\n");
  	if (sc->flags & PCIB_SUBTRACTIVE)
 @@ -502,6 +770,377 @@ pcib_write_ivar(device_t dev, device_t c
      return(ENOENT);
  }
  
 +#ifdef NEW_PCIB
 +static const char *
 +pcib_child_name(device_t child)
 +{
 +	static char buf[64];
 +
 +	if (device_get_nameunit(child) != NULL)
 +		return (device_get_nameunit(child));
 +	snprintf(buf, sizeof(buf), "pci%d:%d:%d:%d", pci_get_domain(child),
 +	    pci_get_bus(child), pci_get_slot(child), pci_get_function(child));
 +	return (buf);
 +}
 +
 +/*
 + * Attempt to allocate a resource from the existing resources assigned
 + * to a window.
 + */
 +static struct resource *
 +pcib_suballoc_resource(struct pcib_softc *sc, struct pcib_window *w,
 +    device_t child, int type, int *rid, u_long start, u_long end, u_long count,
 +    u_int flags)
 +{
 +	struct resource *res;
 +
 +	if (!pcib_is_window_open(w))
 +		return (NULL);
 +
 +	res = rman_reserve_resource(&w->rman, start, end, count,
 +	    flags & ~RF_ACTIVE, child);
 +	if (res == NULL)
 +		return (NULL);
 +
 +	if (bootverbose)
 +		device_printf(sc->dev,
 +		    "allocated %s range (%#lx-%#lx) for rid %x of %s\n",
 +		    w->name, rman_get_start(res), rman_get_end(res), *rid,
 +		    pcib_child_name(child));
 +	rman_set_rid(res, *rid);
 +
 +	/*
 +	 * If the resource should be active, pass that request up the
 +	 * tree.  This assumes the parent drivers can handle
 +	 * activating sub-allocated resources.
 +	 */
 +	if (flags & RF_ACTIVE) {
 +		if (bus_activate_resource(child, type, *rid, res) != 0) {
 +			rman_release_resource(res);
 +			return (NULL);
 +		}
 +	}
 +
 +	return (res);
 +}
 +
 +/*
 + * Attempt to grow a window to make room for a given resource request.
 + * The 'step' parameter is log_2 of the desired I/O window's alignment.
 + */
 +static int
 +pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
 +    u_long start, u_long end, u_long count, u_int flags)
 +{
 +	u_long align, start_free, end_free, front, back;
 +	int error, rid;
 +
 +	/*
 +	 * Clamp the desired resource range to the maximum address
 +	 * this window supports.  Reject impossible requests.
 +	 */
 +	if (!w->valid)
 +		return (EINVAL);
 +	if (end > w->rman.rm_end)
 +		end = w->rman.rm_end;
 +	if (start + count - 1 > end || start + count < start)
 +		return (EINVAL);
 +
 +	/*
 +	 * If there is no resource at all, just try to allocate enough
 +	 * aligned space for this resource.
 +	 */
 +	if (w->res == NULL) {
 +		if (RF_ALIGNMENT(flags) < w->step) {
 +			flags &= ~RF_ALIGNMENT_MASK;
 +			flags |= RF_ALIGNMENT_LOG2(w->step);
 +		}
 +		start &= ~((1ul << w->step) - 1);
 +		end |= ((1ul << w->step) - 1);
 +		count = roundup2(count, 1ul << w->step);
 +		rid = w->reg;
 +		w->res = bus_alloc_resource(sc->dev, type, &rid, start, end,
 +		    count, flags & ~RF_ACTIVE);
 +		if (w->res == NULL) {
 +			if (bootverbose)
 +				device_printf(sc->dev,
 +		    "failed to allocate initial %s window (%#lx-%#lx,%#lx)\n",
 +				    w->name, start, end, count);
 +			return (ENXIO);
 +		}
 +		if (bootverbose)
 +			device_printf(sc->dev,
 +			    "allocated initial %s window of %#lx-%#lx\n",
 +			    w->name, rman_get_start(w->res),
 +			    rman_get_end(w->res));
 +		error = rman_manage_region(&w->rman, rman_get_start(w->res),
 +		    rman_get_end(w->res));
 +		if (error) {
 +			if (bootverbose)
 +				device_printf(sc->dev,
 +				    "failed to add initial %s window to rman\n",
 +				    w->name);
 +			bus_release_resource(sc->dev, type, w->reg, w->res);
 +			w->res = NULL;
 +			return (error);
 +		}
 +		pcib_activate_window(sc, type);
 +		goto updatewin;
 +	}
 +
 +	/*
 +	 * See if growing the window would help.  Compute the minimum
 +	 * amount of address space needed on both the front and back
 +	 * ends of the existing window to satisfy the allocation.
 +	 *
 +	 * For each end, build a candidate region adjusting for the
 +	 * required alignment, etc.  If there is a free region at the
 +	 * edge of the window, grow from the inner edge of the free
 +	 * region.  Otherwise grow from the window boundary.
 +	 *
 +	 * XXX: Special case: if w->res is completely empty and the
 +	 * request size is larger than w->res, we should find the
 +	 * optimal aligned buffer containing w->res and allocate that.
 +	 */
 +	if (bootverbose)
 +		device_printf(sc->dev,
 +		    "attempting to grow %s window for (%#lx-%#lx,%#lx)\n",
 +		    w->name, start, end, count);
 +	align = 1ul << RF_ALIGNMENT(flags);
 +	if (start < rman_get_start(w->res)) {
 +		if (rman_first_free_region(&w->rman, &start_free, &end_free) !=
 +		    0 || start_free != rman_get_start(w->res))
 +			end_free = rman_get_start(w->res) - 1;
 +		if (end_free > end)
 +			end_free = end;
 +
 +		/* Move end_free down until it is properly aligned. */
 +		end_free &= ~(align - 1);
 +		front = end_free - count;
 +
 +		/*
 +		 * The resource would now be allocated at (front,
 +		 * end_free).  Ensure that fits in the (start, end)
 +		 * bounds.  end_free is checked above.  If 'front' is
 +		 * ok, ensure it is properly aligned for this window.
 +		 * Also check for underflow.
 +		 */
 +		if (front >= start && front <= end_free) {
 +			if (bootverbose)
 +				printf("\tfront candidate range: %#lx-%#lx\n",
 +				    front, end_free);
 +			front &= (1ul << w->step) - 1;
 +			front = rman_get_start(w->res) - front;
 +		} else
 +			front = 0;
 +	} else
 +		front = 0;
 +	if (end > rman_get_end(w->res)) {
 +		if (rman_last_free_region(&w->rman, &start_free, &end_free) !=
 +		    0 || end_free != rman_get_end(w->res))
 +			start_free = rman_get_end(w->res) + 1;
 +		if (start_free < start)
 +			start_free = start;
 +
 +		/* Move start_free up until it is properly aligned. */
 +		start_free = roundup2(start_free, align);
 +		back = start_free + count;
 +
 +		/*
 +		 * The resource would now be allocated at (start_free,
 +		 * back).  Ensure that fits in the (start, end)
 +		 * bounds.  start_free is checked above.  If 'back' is
 +		 * ok, ensure it is properly aligned for this window.
 +		 * Also check for overflow.
 +		 */
 +		if (back <= end && start_free <= back) {
 +			if (bootverbose)
 +				printf("\tback candidate range: %#lx-%#lx\n",
 +				    start_free, back);
 +			back = roundup2(back, w->step) - 1;
 +			back -= rman_get_end(w->res);
 +		} else
 +			back = 0;
 +	} else
 +		back = 0;
 +
 +	/*
 +	 * Try to allocate the smallest needed region first.
 +	 * If that fails, fall back to the other region.
 +	 */
 +	error = ENOSPC;
 +	while (front != 0 || back != 0) {
 +		if (front != 0 && (front <= back || back == 0)) {
 +			error = bus_adjust_resource(sc->dev, type, w->res,
 +			    rman_get_start(w->res) - front,
 +			    rman_get_end(w->res));
 +			if (error == 0)
 +				break;
 +			front = 0;
 +		} else {
 +			error = bus_adjust_resource(sc->dev, type, w->res,
 +			    rman_get_start(w->res),
 +			    rman_get_end(w->res) + back);
 +			if (error == 0)
 +				break;
 +			back = 0;
 +		}
 +	}
 +
 +	if (error)
 +		return (error);
 +	if (bootverbose)
 +		device_printf(sc->dev, "grew %s window to %#lx-%#lx\n",
 +		    w->name, rman_get_start(w->res), rman_get_end(w->res));
 +
 +	/* Add the newly allocated region to the resource manager. */
 +	if (w->base != rman_get_start(w->res)) {
 +		KASSERT(w->limit == rman_get_end(w->res), ("both ends moved"));
 +		error = rman_manage_region(&w->rman, rman_get_start(w->res),
 +		    w->base - 1);
 +	} else {
 +		KASSERT(w->limit != rman_get_end(w->res),
 +		    ("neither end moved"));
 +		error = rman_manage_region(&w->rman, w->limit + 1,
 +		    rman_get_end(w->res));
 +	}
 +	if (error) {
 +		if (bootverbose)
 +			device_printf(sc->dev,
 +			    "failed to expand %s resource manager\n", w->name);
 +		bus_adjust_resource(sc->dev, type, w->res, w->base, w->limit);
 +		return (error);
 +	}
 +
 +updatewin:
 +	/* Save the new window. */
 +	w->base = rman_get_start(w->res);
 +	w->limit = rman_get_end(w->res);
 +	KASSERT((w->base & ((1ul << w->step) - 1)) == 0,
 +	    ("start address is not aligned"));
 +	KASSERT((w->limit & ((1ul << w->step) - 1)) == (1ul << w->step) - 1,
 +	    ("end address is not aligned"));
 +	pcib_write_windows(sc, w->mask);
 +	return (0);
 +}
 +
 +/*
 + * We have to trap resource allocation requests and ensure that the bridge
 + * is set up to, or capable of handling them.
 + */
 +struct resource *
 +pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
 +    u_long start, u_long end, u_long count, u_int flags)
 +{
 +	struct pcib_softc *sc;
 +	struct resource *r;
 +
 +	sc = device_get_softc(dev);
 +
 +	/*
 +	 * VGA resources are decoded iff the VGA enable bit is set in
 +	 * the bridge control register.  VGA resources do not fall into
 +	 * the resource windows and are passed up to the parent.
 +	 */
 +	if ((type == SYS_RES_IOPORT && pci_is_vga_ioport_range(start, end)) ||
 +	    (type == SYS_RES_MEMORY && pci_is_vga_memory_range(start, end))) {
 +		if (sc->bridgectl & PCIB_BCR_VGA_ENABLE)
 +			return (bus_generic_alloc_resource(dev, child, type,
 +			    rid, start, end, count, flags));
 +		else
 +			return (NULL);
 +	}
 +
 +	switch (type) {
 +	case SYS_RES_IOPORT:
 +		r = pcib_suballoc_resource(sc, &sc->io, child, type, rid, start,
 +		    end, count, flags);
 +		if (r != NULL)
 +			break;
 +		if (pcib_grow_window(sc, &sc->io, type, start, end, count,
 +		    flags) == 0)
 +			r = pcib_suballoc_resource(sc, &sc->io, child, type,
 +			    rid, start, end, count, flags);
 +		break;
 +	case SYS_RES_MEMORY:
 +		/*
 +		 * For prefetchable resources, prefer the prefetchable
 +		 * memory window, but fall back to the regular memory
 +		 * window if that fails.  Try both windows before
 +		 * attempting to grow a window in case the firmware
 +		 * has used a range in the regular memory window to
 +		 * map a prefetchable BAR.
 +		 */
 +		if (flags & RF_PREFETCHABLE) {
 +			r = pcib_suballoc_resource(sc, &sc->pmem, child, type,
 +			    rid, start, end, count, flags);
 +			if (r != NULL)
 +				break;
 +		}
 +		r = pcib_suballoc_resource(sc, &sc->mem, child, type, rid,
 +		    start, end, count, flags);
 +		if (r != NULL)
 +			break;
 +		if (flags & RF_PREFETCHABLE) {
 +			if (pcib_grow_window(sc, &sc->pmem, type, start, end,
 +			    count, flags) == 0) {
 +				r = pcib_suballoc_resource(sc, &sc->pmem, child,
 +				    type, rid, start, end, count, flags);
 +				if (r != NULL)
 +					break;
 +			}
 +		}
 +		if (pcib_grow_window(sc, &sc->mem, type, start, end, count,
 +		    flags & ~RF_PREFETCHABLE) == 0)
 +			r = pcib_suballoc_resource(sc, &sc->mem, child, type,
 +			    rid, start, end, count, flags);
 +		break;
 +	default:
 +		return (bus_generic_alloc_resource(dev, child, type, rid,
 +		    start, end, count, flags));
 +	}
 +
 +	/*
 +	 * If attempts to suballocate from the window fail but this is a
 +	 * subtractive bridge, pass the request up the tree.
 +	 */
 +	if (sc->flags & PCIB_SUBTRACTIVE && r == NULL)
 +		return (bus_generic_alloc_resource(dev, child, type, rid,
 +		    start, end, count, flags));
 +	return (r);
 +}
 +
 +int
 +pcib_adjust_resource(device_t bus, device_t child, int type, struct resource *r,
 +    u_long start, u_long end)
 +{
 +	struct pcib_softc *sc;
 +
 +	sc = device_get_softc(bus);
 +	if (pcib_is_resource_managed(sc, type, r))
 +		return (rman_adjust_resource(r, start, end));
 +	return (bus_generic_adjust_resource(bus, child, type, r, start, end));
 +}
 +
 +int
 +pcib_release_resource(device_t dev, device_t child, int type, int rid,
 +    struct resource *r)
 +{
 +	struct pcib_softc *sc;
 +	int error;
 +
 +	sc = device_get_softc(dev);
 +	if (pcib_is_resource_managed(sc, type, r)) {
 +		if (rman_get_flags(r) & RF_ACTIVE) {
 +			error = bus_deactivate_resource(child, type, rid, r);
 +			if (error)
 +				return (error);
 +		}
 +		return (rman_release_resource(r));
 +	}
 +	return (bus_generic_release_resource(dev, child, type, rid, r));
 +}
 +#else
  /*
   * We have to trap resource allocation requests and ensure that the bridge
   * is set up to, or capable of handling them.
 @@ -657,6 +1296,7 @@ pcib_alloc_resource(device_t dev, device
  	return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
  	    count, flags));
  }
 +#endif
  
  /*
   * PCIB interface.
 
 Modified: head/sys/dev/pci/pcib_private.h
 ==============================================================================
 --- head/sys/dev/pci/pcib_private.h	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/dev/pci/pcib_private.h	Tue May  3 17:37:24 2011	(r221393)
 @@ -39,6 +39,24 @@
   */
  DECLARE_CLASS(pcib_driver);
  
 +#ifdef NEW_PCIB
 +#define	WIN_IO		0x1
 +#define	WIN_MEM		0x2
 +#define	WIN_PMEM	0x4
 +
 +struct pcib_window {
 +	pci_addr_t	base;		/* base address */
 +	pci_addr_t	limit;		/* topmost address */
 +	struct rman	rman;
 +	struct resource *res;
 +	int		reg;		/* resource id from parent */
 +	int		valid;
 +	int		mask;		/* WIN_* bitmask of this window */
 +	int		step;		/* log_2 of window granularity */
 +	const char	*name;
 +};
 +#endif
 +
  /*
   * Bridge-specific data.
   */
 @@ -53,12 +71,18 @@ struct pcib_softc 
      u_int	pribus;		/* primary bus number */
      u_int	secbus;		/* secondary bus number */
      u_int	subbus;		/* subordinate bus number */
 +#ifdef NEW_PCIB
 +    struct pcib_window io;	/* I/O port window */
 +    struct pcib_window mem;	/* memory window */
 +    struct pcib_window pmem;	/* prefetchable memory window */
 +#else
      pci_addr_t	pmembase;	/* base address of prefetchable memory */
      pci_addr_t	pmemlimit;	/* topmost address of prefetchable memory */
      pci_addr_t	membase;	/* base address of memory window */
      pci_addr_t	memlimit;	/* topmost address of memory window */
      uint32_t	iobase;		/* base address of port window */
      uint32_t	iolimit;	/* topmost address of port window */
 +#endif
      uint16_t	secstat;	/* secondary bus status register */
      uint16_t	bridgectl;	/* bridge control register */
      uint8_t	seclat;		/* secondary bus latency timer */
 @@ -74,6 +98,12 @@ int		pcib_read_ivar(device_t dev, device
  int		pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value);
  struct resource *pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, 
  					    u_long start, u_long end, u_long count, u_int flags);
 +#ifdef NEW_PCIB
 +int		pcib_adjust_resource(device_t bus, device_t child, int type,
 +    struct resource *r, u_long start, u_long end);
 +int		pcib_release_resource(device_t dev, device_t child, int type, int rid,
 +    struct resource *r);
 +#endif
  int		pcib_maxslots(device_t dev);
  uint32_t	pcib_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width);
  void		pcib_write_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, uint32_t val, int width);
 
 Modified: head/sys/i386/pci/pci_bus.c
 ==============================================================================
 --- head/sys/i386/pci/pci_bus.c	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/i386/pci/pci_bus.c	Tue May  3 17:37:24 2011	(r221393)
 @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/kernel.h>
  #include <sys/malloc.h>
  #include <sys/module.h>
 +#include <sys/rman.h>
  #include <sys/sysctl.h>
  
  #include <dev/pci/pcivar.h>
 
 Modified: head/sys/sparc64/pci/apb.c
 ==============================================================================
 --- head/sys/sparc64/pci/apb.c	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/sparc64/pci/apb.c	Tue May  3 17:37:24 2011	(r221393)
 @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/kernel.h>
  #include <sys/module.h>
  #include <sys/bus.h>
 +#include <sys/rman.h>
  
  #include <dev/ofw/ofw_bus.h>
  #include <dev/ofw/openfirm.h>
 
 Modified: head/sys/sparc64/pci/ofw_pcib.c
 ==============================================================================
 --- head/sys/sparc64/pci/ofw_pcib.c	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/sparc64/pci/ofw_pcib.c	Tue May  3 17:37:24 2011	(r221393)
 @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/kernel.h>
  #include <sys/libkern.h>
  #include <sys/module.h>
 +#include <sys/rman.h>
  
  #include <dev/ofw/ofw_bus.h>
  #include <dev/ofw/openfirm.h>
 
 Modified: head/sys/x86/pci/qpi.c
 ==============================================================================
 --- head/sys/x86/pci/qpi.c	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/x86/pci/qpi.c	Tue May  3 17:37:24 2011	(r221393)
 @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/kernel.h>
  #include <sys/malloc.h>
  #include <sys/module.h>
 +#include <sys/rman.h>
  #include <sys/systm.h>
  
  #include <machine/cputypes.h>
 
 Modified: head/sys/x86/x86/mptable_pci.c
 ==============================================================================
 --- head/sys/x86/x86/mptable_pci.c	Tue May  3 16:36:39 2011	(r221392)
 +++ head/sys/x86/x86/mptable_pci.c	Tue May  3 17:37:24 2011	(r221393)
 @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/bus.h>
  #include <sys/kernel.h>
  #include <sys/module.h>
 +#include <sys/rman.h>
  
  #include <dev/pci/pcireg.h>
  #include <dev/pci/pcivar.h>
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: jhb 
State-Changed-When: Tue May 3 18:34:39 UTC 2011 
State-Changed-Why:  
Probable fix committed to HEAD. 


Responsible-Changed-From-To: freebsd-net->jhb 
Responsible-Changed-By: jhb 
Responsible-Changed-When: Tue May 3 18:34:39 UTC 2011 
Responsible-Changed-Why:  
Probable fix committed to HEAD. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=149306 
State-Changed-From-To: patched->closed 
State-Changed-By: jhb 
State-Changed-When: Thu Jul 7 18:57:57 UTC 2011 
State-Changed-Why:  
Fix merged to 8, but note that a custom kernel has to be compiled with 
options NEW_PCIB to enable it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=149306 
>Unformatted:
