The driver will resume in the ACPI thread and run code to wake the device.
If a firmware error occurs then the init task will be scheduled and could
then run in parallel to the wakeup code. This would lead to panics as the
init task ran while we were not yet done with device initialization.
To prevent this problem we now grab the rwlock during wakeup, the same
lock which is used to prevent races between the init task and ioctls.
Problem found by mvs@, who also suggested the fix implemented here and
tested the changes.
ok mvs@
-/* $OpenBSD: if_iwx.c,v 1.152 2023/01/24 16:18:22 stsp Exp $ */
+/* $OpenBSD: if_iwx.c,v 1.153 2023/02/19 12:23:27 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
struct ifnet *ifp = &sc->sc_ic.ic_if;
int err;
+ rw_enter_write(&sc->ioctl_rwl);
+
err = iwx_start_hw(sc);
- if (err)
+ if (err) {
+ rw_exit(&sc->ioctl_rwl);
return err;
+ }
err = iwx_init_hw(sc);
- if (err)
+ if (err) {
+ iwx_stop_device(sc);
+ rw_exit(&sc->ioctl_rwl);
return err;
+ }
refcnt_init(&sc->task_refs);
ifq_clr_oactive(&ifp->if_snd);
else
ieee80211_begin_scan(ifp);
+ rw_exit(&sc->ioctl_rwl);
return 0;
}