Improve nouveau pci attachment code so it waits for the availability of /

before trying to load firmware.

Fixes my PR 54274.

LGTM mrg
This commit is contained in:
wiz 2019-07-03 20:47:22 +00:00
parent 9af28e64c5
commit 2804fa84ba
1 changed files with 32 additions and 11 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: nouveau_pci.c,v 1.23 2018/12/24 08:40:33 mrg Exp $ */
/* $NetBSD: nouveau_pci.c,v 1.24 2019/07/03 20:47:22 wiz Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nouveau_pci.c,v 1.23 2018/12/24 08:40:33 mrg Exp $");
__KERNEL_RCSID(0, "$NetBSD: nouveau_pci.c,v 1.24 2019/07/03 20:47:22 wiz Exp $");
#include <sys/types.h>
#include <sys/device.h>
@ -52,6 +52,7 @@ SIMPLEQ_HEAD(nouveau_pci_task_head, nouveau_pci_task);
struct nouveau_pci_softc {
device_t sc_dev;
struct pci_attach_args sc_pa;
enum {
NOUVEAU_TASK_ATTACH,
NOUVEAU_TASK_WORKQUEUE,
@ -67,6 +68,7 @@ struct nouveau_pci_softc {
static int nouveau_pci_match(device_t, cfdata_t, void *);
static void nouveau_pci_attach(device_t, device_t, void *);
static void nouveau_pci_attach_real(device_t);
static int nouveau_pci_detach(device_t, int);
static bool nouveau_pci_suspend(device_t, const pmf_qual_t *);
@ -110,7 +112,7 @@ nouveau_pci_match(device_t parent, cfdata_t match, void *aux)
* 0x1e80-0x1eff TU104
* 0x1f00-0x1f7f TU106
*/
if (IS_BETWEEN(0x1580, 0x15ff) ||
IS_BETWEEN(0x1b00, 0x1b7f) ||
IS_BETWEEN(0x1b80, 0x1bff) ||
@ -144,22 +146,37 @@ nouveau_pci_attach(device_t parent, device_t self, void *aux)
{
struct nouveau_pci_softc *const sc = device_private(self);
const struct pci_attach_args *const pa = aux;
int error;
pci_aprint_devinfo(pa, NULL);
if (!pmf_device_register(self, &nouveau_pci_suspend, &nouveau_pci_resume))
aprint_error_dev(self, "unable to establish power handler\n");
/*
* Trivial initialization first; the rest will come after we
* have mounted the root file system and can load firmware
* images.
*/
sc->sc_dev = NULL;
sc->sc_pa = *pa;
config_mountroot(self, &nouveau_pci_attach_real);
}
static void
nouveau_pci_attach_real(device_t self)
{
struct nouveau_pci_softc *const sc = device_private(self);
const struct pci_attach_args *const pa = &sc->sc_pa;
int error;
sc->sc_dev = self;
sc->sc_task_state = NOUVEAU_TASK_ATTACH;
SIMPLEQ_INIT(&sc->sc_task_u.attach);
/* Initialize the Linux PCI device descriptor. */
linux_pci_dev_init(&sc->sc_pci_dev, self, device_parent(self), pa, 0);
if (!pmf_device_register(self, &nouveau_pci_suspend,
&nouveau_pci_resume))
aprint_error_dev(self, "unable to establish power handler\n");
sc->sc_task_state = NOUVEAU_TASK_ATTACH;
SIMPLEQ_INIT(&sc->sc_task_u.attach);
/* XXX errno Linux->NetBSD */
error = -nvkm_device_pci_new(&sc->sc_pci_dev,
nouveau_config, nouveau_debug,
@ -204,6 +221,10 @@ nouveau_pci_detach(device_t self, int flags)
struct nouveau_pci_softc *const sc = device_private(self);
int error;
if (sc->sc_dev == NULL)
/* Not done attaching. */
return EBUSY;
/* XXX Check for in-use before tearing it all down... */
error = config_detach_children(self, flags);
if (error)