Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Nov 2010 16:25:28 -0400
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        John Baldwin <jhb@freebsd.org>
Cc:        "Moore, Robert" <robert.moore@intel.com>, freebsd-acpi@freebsd.org, Lin Ming <ming.m.lin@intel.com>, Andriy Gapon <avg@freebsd.org>
Subject:   Re: MacBookPro 5,1
Message-ID:  <201011031625.38864.jkim@FreeBSD.org>
In-Reply-To: <201011031351.18832.jkim@FreeBSD.org>
References:  <201010121209.06397.hselasky@c2i.net> <201011031247.56071.jhb@freebsd.org> <201011031351.18832.jkim@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--Boundary-00=_CVc0MZ2e68ehPVT
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Wednesday 03 November 2010 01:51 pm, Jung-uk Kim wrote:
> On Wednesday 03 November 2010 12:47 pm, John Baldwin wrote:
> > On Wednesday, November 03, 2010 12:25:37 pm Jung-uk Kim wrote:
> > > On Wednesday 03 November 2010 08:28 am, John Baldwin wrote:
> > > > On Tuesday, November 02, 2010 6:32:12 pm Jung-uk Kim wrote:
> > > > > On Tuesday 02 November 2010 05:26 pm, John Baldwin wrote:
> > > > > > On Tuesday, November 02, 2010 4:50:18 pm Jung-uk Kim 
wrote:
> > > > > > > On Tuesday 02 November 2010 04:24 pm, John Baldwin 
wrote:
> > > > > > > > On Tuesday, November 02, 2010 4:14:05 pm Jung-uk Kim
>
> wrote:
> > > > > > > > > On Tuesday 02 November 2010 03:41 pm, John Baldwin
>
> wrote:
> > > > > > > > > > On Tuesday, November 02, 2010 3:29:01 pm Jung-uk
> > > > > > > > > > Kim
> > >
> > > wrote:
> > > > > > > > > > > On Tuesday 02 November 2010 11:29 am, Andriy
> > > > > > > > > > > Gapon
> > >
> > > wrote:
> > > > > > > > > > > > on 29/10/2010 08:51 Andriy Gapon said the
>
> following:
> > > > > > > > > > > > > I guess that a general problem here is that
> > > > > > > > > > > > > it is incorrect to merely use memcpy/bcopy
> > > > > > > > > > > > > to create a copy of a resource if the
> > > > > > > > > > > > > resource has ACPI_RESOURCE_SOURCE field in
> > > > > > > > > > > > > it.
> > > > > > > > > > > >
> > > > > > > > > > > > Hans,
> > > > > > > > > > > >
> > > > > > > > > > > > could you please test the following patch?
> > > > > > > > > > > >
> > > > > > > > > > > > diff --git a/sys/dev/acpica/acpi_pci_link.c
> > > > > > > > > > > > b/sys/dev/acpica/acpi_pci_link.c index
> > > > > > > > > > > > dcf101d..e842635 100644 ---
> > > > > > > > > > > > a/sys/dev/acpica/acpi_pci_link.c +++
> > > > > > > > > > > > b/sys/dev/acpica/acpi_pci_link.c
> > > > > > > > > > > > @@ -767,6 +767,8 @@
> > > > > > > > > > > > acpi_pci_link_srs_from_crs link->l_irq;
> > > > > > > > > > > >  			else
> > > > > > > > > > > >  				resptr->Data.ExtendedIrq.Interrupts[0] =
> > > > > > > > > > > > 0;
> > > > > > > > > > > > +			memset(&resptr->Data.ExtendedIrq.Resource
> > > > > > > > > > > >So urce , 0, +			   
> > > > > > > > > > > > sizeof(ACPI_RESOURCE_SOURCE)); link++;
> > > > > > > > > > > >  			i++;
> > > > > > > > > > > >  			break;
> > > > > > > > > > >
> > > > > > > > > > > Hmm...  Very interesting.  Can you please try
> > > > > > > > > > > this, too?
> > > > > > > > > >
> > > > > > > > > > Linux doesn't set the resource source bits up at
> > > > > > > > > > all when doing _SRS, so I'd rather just do that. 
> > > > > > > > > > I think what I'd prefer is that we not use the
> > > > > > > > > > prs_template, perhaps just save the type of the
> > > > > > > > > > resource and build a new resource object from
> > > > > > > > > > scratch where the resource is zero'd, the
> > > > > > > > > > appropriate bits are set and then that resource
> > > > > > > > > > is appended to the buffer being built.
> > > > > > > > >
> > > > > > > > > "Linux doesn't do it" is wrong if I am reading the
> > > > > > > > > spec. correctly, i.e., _CRS, _PRS and _SRS must
> > > > > > > > > have the same format and size.
> > > > > > > >
> > > > > > > > Umm, but we aren't setting up the raw bits for _SRS.
> > > > > > > > We are creating a list of ACPI_RESOURCE objects that
> > > > > > > > ACPICA then encodes into a buffer to send to _SRS.
> > > > > > >
> > > > > > > Yes, I understand.  However, ACPICA is expecting the
> > > > > > > same size of buffer *including* the optional parts if I
> > > > > > > am reading the code right. Besides, I don't think there
> > > > > > > is any harm in doing the right thing. ;-)
> > > > > >
> > > > > > To be clear, I am suggesting to take an ACPI_RESOURCE
> > > > > > object, bzero it, then set the type and the IRQ and
> > > > > > that's it.  Leave the ResourceSource bits as zero.  The
> > > > > > size will still be set based on the actual type (or if
> > > > > > needed we can use the cached size from the template copy
> > > > > > we save from _PRS).  The point would be to start from a
> > > > > > zero structure instead of from a copy of what we got from
> > > > > > _PRS.
> > > > >
> > > > > It may work if we don't use l_prs_template.
> > > >
> > > > Well, we still need much of the info from the _PRS resource
> > > > (the type, etc.), but I think we should not blindly use the
> > > > template directly when building the buffer for _SRS.
> > >
> > > Actually, I think we should get the information directly from
> > > _CRS as ACPI spec. is suggesting.
> >
> > I would be fine with that, but that does not work if _CRS doesn't
> > work (the acpi_pci_link_srs_from_links() case).
>
> For that case, we must use the template, of course.  In fact, my
> patch is more useful for this particular case. :-)
>
> > Are we allowed to modify the buffer ACPICA gives us from _CRS and
> > then pass that back to _SRS?
>
> I believe so.  If we go with that route, we don't have to worry
> about ResourceSource.StringPtr or acpi_AppendBufferResource()
> copying stale pointers.

Please see the attached patch.  It seems working fine. :-)

Note I had to adjust resource length to prevent reading/writing beyond 
buffer size.  It should work okay for acpi_pci_link_srs_from_links() 
case, I believe.  It's a hack anyway. ;-)

Jung-uk Kim

--Boundary-00=_CVc0MZ2e68ehPVT
Content-Type: text/plain; charset="iso-8859-1"; name="acpi_pci_link2.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="acpi_pci_link2.diff"

--- sys/dev/acpica/acpi_pci_link.c	2010-03-05 15:07:53.000000000 -0500
+++ sys/dev/acpica/acpi_pci_link.c	2010-11-03 16:09:40.000000000 -0400
@@ -268,6 +268,7 @@ link_add_crs(ACPI_RESOURCE *res, void *c
 static ACPI_STATUS
 link_add_prs(ACPI_RESOURCE *res, void *context)
 {
+	ACPI_RESOURCE *tmp;
 	struct link_res_request *req;
 	struct link *link;
 	UINT8 *irqs = NULL;
@@ -321,8 +322,17 @@ link_add_prs(ACPI_RESOURCE *res, void *c
 		 * Stash a copy of the resource for later use when doing
 		 * _SRS.
 		 */
-		bcopy(res, &link->l_prs_template, sizeof(ACPI_RESOURCE));
+		tmp = &link->l_prs_template;
+		bcopy(res, tmp, sizeof(*res));
 		if (is_ext_irq) {
+			/*
+			 * XXX acpi_AppendBufferResource() cannot handle
+			 * optional ResourceSource.
+			 */
+			bzero(&tmp->Data.ExtendedIrq.ResourceSource,
+			    sizeof(tmp->Data.ExtendedIrq.ResourceSource));
+			tmp->Length = sizeof(tmp->Data.ExtendedIrq);
+
 			link->l_num_irqs =
 			    res->Data.ExtendedIrq.InterruptCount;
 			ext_irqs = res->Data.ExtendedIrq.Interrupts;
@@ -688,18 +698,17 @@ acpi_pci_link_add_reference(device_t dev
 static ACPI_STATUS
 acpi_pci_link_srs_from_crs(struct acpi_pci_link_softc *sc, ACPI_BUFFER *srsbuf)
 {
-	ACPI_RESOURCE *resource, *end, newres, *resptr;
-	ACPI_BUFFER crsbuf;
+	ACPI_RESOURCE *end, *res;
 	ACPI_STATUS status;
 	struct link *link;
 	int i, in_dpf;
 
 	/* Fetch the _CRS. */
 	ACPI_SERIAL_ASSERT(pci_link);
-	crsbuf.Pointer = NULL;
-	crsbuf.Length = ACPI_ALLOCATE_BUFFER;
-	status = AcpiGetCurrentResources(acpi_get_handle(sc->pl_dev), &crsbuf);
-	if (ACPI_SUCCESS(status) && crsbuf.Pointer == NULL)
+	srsbuf->Pointer = NULL;
+	srsbuf->Length = ACPI_ALLOCATE_BUFFER;
+	status = AcpiGetCurrentResources(acpi_get_handle(sc->pl_dev), srsbuf);
+	if (ACPI_SUCCESS(status) && srsbuf->Pointer == NULL)
 		status = AE_NO_MEMORY;
 	if (ACPI_FAILURE(status)) {
 		if (bootverbose)
@@ -710,14 +719,13 @@ acpi_pci_link_srs_from_crs(struct acpi_p
 	}
 
 	/* Fill in IRQ resources via link structures. */
-	srsbuf->Pointer = NULL;
 	link = sc->pl_links;
 	i = 0;
 	in_dpf = DPF_OUTSIDE;
-	resource = (ACPI_RESOURCE *)crsbuf.Pointer;
-	end = (ACPI_RESOURCE *)((char *)crsbuf.Pointer + crsbuf.Length);
+	res = (ACPI_RESOURCE *)srsbuf->Pointer;
+	end = (ACPI_RESOURCE *)((char *)srsbuf->Pointer + srsbuf->Length);
 	for (;;) {
-		switch (resource->Type) {
+		switch (res->Type) {
 		case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 			switch (in_dpf) {
 			case DPF_OUTSIDE:
@@ -731,67 +739,44 @@ acpi_pci_link_srs_from_crs(struct acpi_p
 				    __func__);
 				break;
 			}
-			resptr = NULL;
 			break;
 		case ACPI_RESOURCE_TYPE_END_DEPENDENT:
 			/* We are finished with DPF parsing. */
 			KASSERT(in_dpf != DPF_OUTSIDE,
 			    ("%s: end dpf when not parsing a dpf", __func__));
 			in_dpf = DPF_OUTSIDE;
-			resptr = NULL;
 			break;
 		case ACPI_RESOURCE_TYPE_IRQ:
 			MPASS(i < sc->pl_num_links);
-			MPASS(link->l_prs_template.Type == ACPI_RESOURCE_TYPE_IRQ);
-			newres = link->l_prs_template;
-			resptr = &newres;
-			resptr->Data.Irq.InterruptCount = 1;
+			res->Data.Irq.InterruptCount = 1;
 			if (PCI_INTERRUPT_VALID(link->l_irq)) {
 				KASSERT(link->l_irq < NUM_ISA_INTERRUPTS,
 		("%s: can't put non-ISA IRQ %d in legacy IRQ resource type",
 				    __func__, link->l_irq));
-				resptr->Data.Irq.Interrupts[0] = link->l_irq;
+				res->Data.Irq.Interrupts[0] = link->l_irq;
 			} else
-				resptr->Data.Irq.Interrupts[0] = 0;
+				res->Data.Irq.Interrupts[0] = 0;
 			link++;
 			i++;
 			break;
 		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 			MPASS(i < sc->pl_num_links);
-			MPASS(link->l_prs_template.Type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ);
-			newres = link->l_prs_template;
-			resptr = &newres;
-			resptr->Data.ExtendedIrq.InterruptCount = 1;
+			res->Data.ExtendedIrq.InterruptCount = 1;
 			if (PCI_INTERRUPT_VALID(link->l_irq))
-				resptr->Data.ExtendedIrq.Interrupts[0] =
+				res->Data.ExtendedIrq.Interrupts[0] =
 				    link->l_irq;
 			else
-				resptr->Data.ExtendedIrq.Interrupts[0] = 0;
+				res->Data.ExtendedIrq.Interrupts[0] = 0;
 			link++;
 			i++;
 			break;
-		default:
-			resptr = resource;
 		}
-		if (resptr != NULL) {
-			status = acpi_AppendBufferResource(srsbuf, resptr);
-			if (ACPI_FAILURE(status)) {
-				device_printf(sc->pl_dev,
-				    "Unable to build resources: %s\n",
-				    AcpiFormatException(status));
-				if (srsbuf->Pointer != NULL)
-					AcpiOsFree(srsbuf->Pointer);
-				AcpiOsFree(crsbuf.Pointer);
-				return (status);
-			}
-		}
-		if (resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
+		if (res->Type == ACPI_RESOURCE_TYPE_END_TAG)
 			break;
-		resource = ACPI_NEXT_RESOURCE(resource);
-		if (resource >= end)
+		res = ACPI_NEXT_RESOURCE(res);
+		if (res >= end)
 			break;
 	}
-	AcpiOsFree(crsbuf.Pointer);
 	return (AE_OK);
 }
 

--Boundary-00=_CVc0MZ2e68ehPVT--



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