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
--- 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);
 }
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-acpi
To unsubscribe, send any mail to "[email protected]"

Reply via email to