MacBookPro 5,1
Jung-uk Kim
jkim at FreeBSD.org
Wed Nov 3 20:25:47 UTC 2010
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
-------------- next part --------------
--- 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);
}
More information about the freebsd-acpi
mailing list