There are two paths in the LinuxKPI PCI code to instantiate a "pdev"
(LinuxKPI pci_dev). One is using the FreeBSD bus framework and the
pdev will be the softc.
This commit starts cleaning up the detach path for just that case
to the best possible.
So far we did a lot of the work in linux_pci_detach_device(), which is
the internal handler of the detach function and little in the
(*release) callback (devres cleanup only).
The problem with that is, that we teardown resources which later in the
devres cleanup are needed. With them not being there anymore we panic, e.g.,
in lkpi_dma_unmap < lkpi_dmam_free_coherent < lkpi_devres_release_free_list).
The solution is to migrate most of the cleanup work into the (*release)
callback, which will automatically be called when the device (kobj) reference
drops to zero. The only work which should be done immediately is let the
dirver do its cleanup; this has to happen before we try to teardown the
resources, but also we do want this to happen when detach is called
(the first time).
One problem we have with the deferred cleanup of the remaining parts is
that we do not know upon calling pci_dev_put() whether this cleared
the last reference and triggered the cleanup or not but we cannot return
from the detach function with pending resources and dangling pointers,
which then may be used. In order to work around this, we clear the
(*release) callback function when it is run and check for that in the
detach routine. If the (*release) callback was not run, we refuse to
detach (force would be needed) as we'd rather keep the device than
risk a follow-up panic on leaked resources. Given this should not happen
in a well programmed world, I believe it is fine to take that and log it
to let the user know.
Try to leave a few comments behind to help with understanding in the
future.
With this we can unload the mt7921 driver (or shutdown the system)
without panic.
Sponsored by: The FreeBSD Foundation
MFC after: 3 days