Applied, thanks! Damien Zammit via Bug reports for the GNU Hurd, le sam. 28 déc. 2024 02:36:06 +0000, a ecrit: > This mostly fixes the numbering of IRQs when requested. > This now works on an old AMD board with broken _CRS. > It requests the possible irqs from _PRS and generates > a valid _SRS request to set the one from the end of the list. > > v2: It also no longer errors on a valid _CRS. > > --- > debian/patches/acpi-init-files.diff | 327 +++++++++++++++++++--------- > 1 file changed, 221 insertions(+), 106 deletions(-) > > diff --git a/debian/patches/acpi-init-files.diff > b/debian/patches/acpi-init-files.diff > index eb7482c..f45cec9 100644 > --- a/debian/patches/acpi-init-files.diff > +++ b/debian/patches/acpi-init-files.diff > @@ -1,6 +1,6 @@ > --- /dev/null > +++ b/acpi_init.c > -@@ -0,0 +1,597 @@ > +@@ -0,0 +1,712 @@ > +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 > +#include <acpi/acpi.h> > + > @@ -32,6 +32,9 @@ > +#define PCI_CFG1_START 0xcf8 > +#define PCI_CFG1_END 0xcff > + > ++#define LEGACY_ISA_IRQS 8 > ++#define PCI_IRQ_START 16 > ++ > +extern acpi_status acpi_hw_legacy_sleep(u8 sleep_state); > + > +// Lets keep the ACPI tables in this module > @@ -361,162 +364,165 @@ > + acpi_hw_legacy_sleep (sleep_state); > +} > + > ++ > +static acpi_status > -+register_slot(acpi_handle handle, u32 lev, void *context, void **rv) > ++acpi_pci_link_count_all(struct acpi_resource *resource, void *context) > +{ > -+ if (!context) > -+ return AE_ERROR; > ++ int *count = (int *)context; > + > -+ u64 addr, addr_bus; > -+ acpi_status err; > ++ (*count)++; > + > -+ struct slots *s = (void *)malloc(sizeof (struct slots)); > -+ if (!s) > -+ return -1; > -+ > -+ { > -+ struct acpi_buffer buffer = { 0, NULL }; > -+ union acpi_object element; > -+ buffer.length = sizeof(union acpi_object); > -+ buffer.pointer = &element; > -+ err = acpi_evaluate_object(handle, METHOD_NAME__BBN, NULL, &buffer); > -+ if (ACPI_SUCCESS(err) && element.type == ACPI_TYPE_INTEGER) > -+ addr_bus = element.integer.value; > -+ else if (err == AE_NOT_FOUND) > -+ addr_bus = 0; > -+ else > -+ { > -+ free(s); > -+ return AE_ERROR; > -+ } > -+ } > -+ > -+ s->bus = addr_bus & 0xff; > -+ > -+ { > -+ struct acpi_buffer buffer = { 0, NULL }; > -+ union acpi_object element; > -+ buffer.length = sizeof(union acpi_object); > -+ buffer.pointer = &element; > -+ > -+ err = acpi_evaluate_object(handle, METHOD_NAME__ADR, NULL, &buffer); > -+ if (ACPI_SUCCESS(err) && element.type == ACPI_TYPE_INTEGER) > -+ addr = element.integer.value; > -+ else if (err == AE_NOT_FOUND) > -+ { > -+ free(s); > -+ return AE_OK; > -+ } > -+ else > -+ { > -+ free(s); > -+ return AE_ERROR; > -+ } > -+ } > -+ > -+ s->dev = (addr >> 16) & 0xffff; > -+ s->func = addr & 0xffff; > -+ s->handle = handle; > -+ s->next = NULL; > -+ > -+ struct slots **slot_ptr_ptr = (struct slots **)(context); > -+ if (!(*slot_ptr_ptr)) > -+ *slot_ptr_ptr = s; > -+ else > ++ return AE_OK; > ++} > ++ > ++static acpi_status > ++acpi_pci_link_count_irq(struct acpi_resource *resource, void *context) > ++{ > ++ int *count = (int *)context; > ++ > ++ if (!resource->length) > ++ return AE_OK; > ++ > ++ switch (resource->type) > + { > -+ struct slots *slot_ptr = *slot_ptr_ptr; > -+ while(slot_ptr->next) > -+ slot_ptr = slot_ptr->next; > -+ slot_ptr->next = s; > ++ case ACPI_RESOURCE_TYPE_IRQ: > ++ { > ++ struct acpi_resource_irq *irq_resource = &resource->data.irq; > ++ if (!irq_resource || !irq_resource->interrupt_count || > !irq_resource->interrupts[0]) > ++ return AE_OK; > ++ (*count)++; > ++ } > ++ break; > ++ case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: > ++ { > ++ struct acpi_resource_extended_irq *irq_resource = > &resource->data.extended_irq; > ++ if (!irq_resource || !irq_resource->interrupt_count || > !irq_resource->interrupts[0]) > ++ return AE_OK; > ++ (*count)++; > ++ } > ++ break; > ++ default: > ++ break; > ++ } > ++ > ++ return AE_OK; > ++} > ++ > ++static acpi_status > ++acpi_pci_link_subset_last_irq(struct acpi_resource *resource, void *context) > ++{ > ++ struct acpi_resource *res = (struct acpi_resource *)context; > ++ > ++ switch (resource->type) > ++ { > ++ case ACPI_RESOURCE_TYPE_IRQ: > ++ { > ++ struct acpi_resource_irq *irq_resource = &resource->data.irq; > ++ if (!irq_resource || !irq_resource->interrupt_count || > !irq_resource->interrupts[0]) > ++ return AE_OK; > ++ *res = *resource; > ++ return AE_OK; > ++ } > ++ break; > ++ case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: > ++ { > ++ struct acpi_resource_extended_irq *irq_resource = > &resource->data.extended_irq; > ++ if (!irq_resource || !irq_resource->interrupt_count || > !irq_resource->interrupts[0]) > ++ return AE_OK; > ++ *res = *resource; > ++ return AE_OK; > ++ } > ++ break; > ++ default: > ++ break; > + } > ++ > + return AE_OK; > +} > + > +static acpi_status > -+acpi_pci_link_check(struct acpi_resource *resource, void *context) > ++acpi_pci_link_get_last_valid_irq(struct acpi_resource *resource, void > *context) > +{ > + int *irq = (int *)context; > + > ++ if (!resource->length) > ++ { > ++ acpi_os_printf("Empty resource\n"); > ++ return AE_OK; > ++ } > ++ > + switch (resource->type) > + { > + case ACPI_RESOURCE_TYPE_IRQ: > + { > + struct acpi_resource_irq *irq_resource = &resource->data.irq; > -+ if (!irq_resource || !irq_resource->interrupt_count) > ++ if (!irq_resource || !irq_resource->interrupt_count || > !irq_resource->interrupts[0]) > + { > + // no IRQ# bits set generally w/ _STA disabled > + acpi_os_printf("Empty _CRS IRQ resource\n"); > + return AE_OK; > + } > + *irq = irq_resource->interrupts[0]; > -+ break; > + } > ++ break; > + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: > + { > + struct acpi_resource_extended_irq *irq_resource = > &resource->data.extended_irq; > -+ if (!irq_resource || !irq_resource->interrupt_count) > ++ if (!irq_resource || !irq_resource->interrupt_count || > !irq_resource->interrupts[0]) > + { > + // extended IRQ descriptors should return at least 1 IRQ > + acpi_os_printf("Empty _CRS EXT IRQ resource\n"); > + return AE_OK; > + } > + *irq = irq_resource->interrupts[0]; > -+ break; > + } > ++ break; > ++ case ACPI_RESOURCE_TYPE_END_TAG: > ++ return AE_OK; > ++ break; > + default: > ++ acpi_os_printf("Not IRQ resource\n"); > + return AE_OK; > + } > + > -+ return AE_CTRL_TERMINATE; > ++ acpi_os_printf("Found IRQ resource %d\n", *irq); > ++ return AE_OK; > +} > + > +int > +acpi_get_irq_number(uint16_t bus, uint16_t dev, uint16_t func) > +{ > + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; > ++ struct acpi_buffer srs_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; > + struct acpi_pci_routing_table *entry; > ++ struct acpi_resource *res; > ++ uint8_t *buf; > ++ int srs_count; > ++ > + acpi_handle handle = ACPI_ROOT_OBJECT; > + acpi_handle parent_handle = NULL; > ++ acpi_handle prt = NULL; > + acpi_handle lnk = NULL; > + acpi_status err = AE_OK; > + u16 prt_dev, prt_func; > -+ struct slots *pcislots = NULL, *iter; > -+ int nslots = 0; > + > -+ err = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, INT_MAX, > register_slot, NULL, (struct slots **)&pcislots, NULL); > ++ err = acpi_get_handle(handle, "\\_SB.PCI0", &parent_handle); > + if (ACPI_FAILURE(err)) > + return -EIO; > + > -+ for (iter = pcislots; iter; iter = iter->next) > -+ { > -+ if ((iter->bus == bus) && (iter->dev == dev) && (iter->func == func)) > -+ { > -+ handle = iter->handle; > -+ break; > -+ } > -+ nslots++; > -+ } > ++ err = acpi_get_handle(parent_handle, METHOD_NAME__PRT, &prt); > ++ if (ACPI_FAILURE(err)) > ++ return -EIO; > + > -+ err = acpi_get_parent(handle, &parent_handle); > ++ err = acpi_evaluate_object(prt, NULL, NULL, &buffer); > + if (ACPI_FAILURE(err)) > + return -EIO; > + > + err = acpi_get_irq_routing_table(parent_handle, &buffer); > + if (ACPI_FAILURE(err)) > -+ { > -+ free(buffer.pointer); > -+ // free pcislots allocated in register_slot function > -+ struct slots *current_pcislot = pcislots; > -+ while (current_pcislot) > -+ { > -+ free(current_pcislot); > -+ pcislots = pcislots->next; > -+ current_pcislot = pcislots; > -+ } > -+ return -EIO; > -+ } > ++ return -EIO; > + > -+ entry = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer.pointer); > ++ entry = ACPI_CAST_PTR(struct acpi_pci_routing_table, ACPI_CAST_PTR(u8, > buffer.pointer)); > + while (entry && (entry->length > 0)) > + { > + /* Already applies to the bus of the device */ > @@ -525,28 +531,137 @@ > + if ((prt_dev == dev) && (prt_func == 0xffff)) > + { > + if (entry->source[0]) > -+ { > ++ { > ++ int crs_count = 0; > ++ int prs_count_irq = 0; > ++ int prs_count_all = 0; > ++ int irq = -1; > ++ > + /* Dynamic: > + * - source field specifies PCI interrupt LNK > + * - source_index specifies which resource descriptor in > + * resource template of LNK to allocate this interrupt > + */ > -+ err = acpi_get_handle(handle, entry->source, &lnk); > ++ err = acpi_get_handle(ACPI_ROOT_OBJECT, entry->source, &lnk); > + if (ACPI_FAILURE(err)) > + return -EIO; > + > + if (!lnk) > -+ acpi_os_printf("error invalid lnk"); > -+ > -+ int irq = -1; > -+ err = acpi_walk_resources(lnk, METHOD_NAME__CRS, > acpi_pci_link_check, &irq); > ++ { > ++ acpi_os_printf("Error invalid lnk\n"); > ++ return -EIO; > ++ } > ++ > ++ err = acpi_walk_resources(lnk, "_CRS", > acpi_pci_link_count_irq, &crs_count); > ++ if (ACPI_FAILURE(err) || !crs_count) > ++ acpi_os_printf("Warning: missing _CRS\n"); > ++ acpi_walk_resources(lnk, "_PRS", acpi_pci_link_count_all, > &prs_count_all); > ++ err = acpi_walk_resources(lnk, "_PRS", > acpi_pci_link_count_irq, &prs_count_irq); > + if (ACPI_FAILURE(err)) > -+ return -EIO; > -+ return irq; > -+ // FIXME check the LNK irq _CRS and then set it with _SRS > ++ { > ++ if (crs_count == 0) > ++ { > ++ acpi_os_printf("Error: missing _PRS when needed\n"); > ++ return -EIO; > ++ } > ++ } > ++ if (crs_count > 0) > ++ { > ++ irq = 0; > ++ err = acpi_walk_resources(lnk, "_CRS", > acpi_pci_link_get_last_valid_irq, &irq); > ++ if (ACPI_FAILURE(err) || !irq) > ++ { > ++ acpi_os_printf("Error walk_resources _CRS\n"); > ++ return -EIO; > ++ } > ++ > ++ err = acpi_get_current_resources(lnk, &srs_buffer); > ++ if (ACPI_FAILURE(err)) > ++ { > ++ acpi_os_printf("Error getting _CRS\n"); > ++ return -EIO; > ++ } > ++ > ++ err = acpi_set_current_resources(lnk, &srs_buffer); > ++ if (ACPI_FAILURE(err)) > ++ { > ++ acpi_os_printf("Error setting _SRS\n"); > ++ return -EIO; > ++ } > ++ irq += (irq > LEGACY_ISA_IRQS) ? 0 : PCI_IRQ_START; > ++ acpi_os_printf("Final irq %d\n", irq); > ++ return irq; > ++ } > ++ else if (prs_count_irq > 0) > ++ { > ++ irq = 0; > ++ err = acpi_walk_resources(lnk, "_PRS", > acpi_pci_link_get_last_valid_irq, &irq); > ++ if (ACPI_FAILURE(err) || !irq) > ++ { > ++ acpi_os_printf("Error walk_resources _PRS\n"); > ++ return -EIO; > ++ } > ++ > ++ if (irq > 16) > ++ { > ++ acpi_os_printf("Error IRQ > 16, not implemented\n"); > ++ return -EIO; > ++ } > ++ > ++ /* Found a possible irq, but need to call _SRS to set it > */ > ++ > ++ /* IRQ resource + end tagged resource */ > ++ srs_count = 2; > ++ > ++ res = (struct acpi_resource *)calloc(1, srs_count * > sizeof(struct acpi_resource)); > ++ > ++ err = acpi_walk_resources(lnk, "_PRS", > acpi_pci_link_subset_last_irq, res); > ++ if (err) > ++ { > ++ acpi_os_printf("Error _PRS cannot be read\n"); > ++ free(res); > ++ return -EIO; > ++ } > ++ > ++ /* Patch the _PRS to use for _SRS */ > ++ srs_buffer.length = sizeof(struct acpi_resource) + 1; > ++ srs_buffer.pointer = res; > ++ > ++ switch (res->type) > ++ { > ++ case ACPI_RESOURCE_TYPE_IRQ: > ++ res->data.irq.interrupt_count = 1; > ++ res->data.irq.interrupts[0] = irq; > ++ break; > ++ case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: > ++ res->data.extended_irq.interrupt_count = 1; > ++ res->data.extended_irq.interrupts[0] = irq; > ++ break; > ++ } > ++ > ++ res[1].type = ACPI_RESOURCE_TYPE_END_TAG; > ++ res[1].length = sizeof(struct acpi_resource); > ++ > ++ err = acpi_set_current_resources(lnk, &srs_buffer); > ++ if (ACPI_FAILURE(err)) > ++ { > ++ acpi_os_printf("Error setting _SRS\n"); > ++ free(res); > ++ return -EIO; > ++ } > ++ free(res); > ++ irq += (irq > LEGACY_ISA_IRQS) ? 0 : PCI_IRQ_START; > ++ acpi_os_printf("Final irq %d\n", irq); > ++ return irq; > ++ } > ++ else > ++ { > ++ acpi_os_printf("Error: _CRS has empty IRQ resources\n"); > ++ return -EIO; > ++ } > + } > -+ else > -+ { > ++ else > ++ { > + /* Static: > + * - source field is zero > + * - source_index specifies IRQ value hardwired to > -- > 2.45.2 > > >
-- Samuel RR> Ce que je cherche à démontrer, c'est qu'il est injuste de faire RR> l'amalgame entre du bulk mail et du courrier non-solicité très ciblé un suppositoire non reclamé, meme tres bien ciblé, reste un suppositoire. -+-OS in : Guide du Neuneu d'Usenet - Plein le cul de la pub à neuneu -+-