On Mon, May 21, 2018 at 01:22:50AM +0200, Mark Kettenis wrote:
> Diff below does two things:
> 
> 1. Put controllers and child devices into _PS0.  It seems the BIOS is
>    supposed to deliver them to us in that state, but apparently some
>    BIOSen don't do that.
> 
> 2. Override the card detect if ACPI says that the child devices are
>    non-removable.  Apparently SDHC card detect is borked (or simply
>    not implemented) on the Intel SDIO controllers.
> 
> With these diffs, the SDIO WiFi in my Asus X205TA is probed correctly.
> And it even works with the bwfm(4) driver after some further magic.
> 
> ok?
> 

Explanation makes sense and diff reads ok.

ok mlarkin

> 
> Index: dev/acpi/sdhc_acpi.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/sdhc_acpi.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 sdhc_acpi.c
> --- dev/acpi/sdhc_acpi.c      25 Oct 2016 06:48:58 -0000      1.9
> +++ dev/acpi/sdhc_acpi.c      20 May 2018 23:14:26 -0000
> @@ -70,8 +70,11 @@ const char *sdhc_hids[] = {
>  };
>  
>  int  sdhc_acpi_parse_resources(int, union acpi_resource *, void *);
> -int  sdhc_acpi_card_detect(struct sdhc_softc *);
> +int  sdhc_acpi_card_detect_nonremovable(struct sdhc_softc *);
> +int  sdhc_acpi_card_detect_gpio(struct sdhc_softc *);
>  int  sdhc_acpi_card_detect_intr(void *);
> +void sdhc_acpi_power_on(struct sdhc_acpi_softc *, struct aml_node *);
> +void sdhc_acpi_explore(struct sdhc_acpi_softc *);
>  
>  int
>  sdhc_acpi_match(struct device *parent, void *match, void *aux)
> @@ -122,10 +125,12 @@ sdhc_acpi_attach(struct device *parent, 
>       }
>  
>       if (sc->sc_gpio_io_node && sc->sc_gpio_io_node->gpio) {
> -             sc->sc.sc_card_detect = sdhc_acpi_card_detect;
> +             sc->sc.sc_card_detect = sdhc_acpi_card_detect_gpio;
>               printf(", gpio");
>       }
>  
> +     printf("\n");
> +
>       if (sc->sc_gpio_int_node && sc->sc_gpio_int_node->gpio) {
>               struct acpi_gpio *gpio = sc->sc_gpio_int_node->gpio;
>  
> @@ -133,7 +138,8 @@ sdhc_acpi_attach(struct device *parent, 
>                   sc->sc_gpio_int_flags, sdhc_acpi_card_detect_intr, sc);
>       }
>  
> -     printf("\n");
> +     sdhc_acpi_power_on(sc, sc->sc_node);
> +     sdhc_acpi_explore(sc);
>  
>       sc->sc.sc_host = &sc->sc_host;
>       sc->sc.sc_dmat = &pci_bus_dma_tag;
> @@ -175,7 +181,13 @@ sdhc_acpi_parse_resources(int crsidx, un
>  }
>  
>  int
> -sdhc_acpi_card_detect(struct sdhc_softc *ssc)
> +sdhc_acpi_card_detect_nonremovable(struct sdhc_softc *ssc)
> +{
> +     return 1;
> +}
> +
> +int
> +sdhc_acpi_card_detect_gpio(struct sdhc_softc *ssc)
>  {
>       struct sdhc_acpi_softc *sc = (struct sdhc_acpi_softc *)ssc;
>       struct acpi_gpio *gpio = sc->sc_gpio_io_node->gpio;
> @@ -193,4 +205,48 @@ sdhc_acpi_card_detect_intr(void *arg)
>       sdhc_needs_discover(&sc->sc);
>  
>       return (1);
> +}
> +
> +void
> +sdhc_acpi_power_on(struct sdhc_acpi_softc *sc, struct aml_node *node)
> +{
> +     node = aml_searchname(node, "_PS0");
> +     if (node && aml_evalnode(sc->sc_acpi, node, 0, NULL, NULL))
> +             printf("%s: _PS0 failed\n", sc->sc.sc_dev.dv_xname);
> +}
> +
> +int
> +sdhc_acpi_do_explore(struct aml_node *node, void *arg)
> +{
> +     struct sdhc_acpi_softc *sc = arg;
> +     int64_t sta, rmv;
> +
> +     /* We're only interested in our children. */
> +     if (node == sc->sc_node)
> +             return 0;
> +
> +     /* Only consider devices that are actually present. */
> +     if (node->value == NULL ||
> +         node->value->type != AML_OBJTYPE_DEVICE)
> +             return 1;
> +     if (aml_evalinteger(sc->sc_acpi, node, "_STA", 0, NULL, &sta))
> +             sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000;
> +     if ((sta & STA_PRESENT) == 0)
> +             return 1;
> +
> +     /* Override card detect if we have non-removable devices. */
> +     if (aml_evalinteger(sc->sc_acpi, node, "_RMV", 0, NULL, &rmv))
> +             rmv = 1;
> +     if (rmv == 0 && sc->sc.sc_card_detect == NULL)
> +             sc->sc.sc_card_detect = sdhc_acpi_card_detect_nonremovable;
> +
> +     sdhc_acpi_power_on(sc, node);
> +
> +     return 1;
> +}
> +
> +void
> +sdhc_acpi_explore(struct sdhc_acpi_softc *sc)
> +{
> +     aml_walknodes(sc->sc_node, AML_WALK_PRE, sdhc_acpi_do_explore, sc);
>  }
> 

Reply via email to