git: 84fc080266e1 - stable/13 - cxgbe: Deactivate upper layer drivers (like TOE) during detach.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Thu, 25 Aug 2022 17:31:30 UTC
The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=84fc080266e1b00134d23217e918b4a48b7963d2

commit 84fc080266e1b00134d23217e918b4a48b7963d2
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-05-17 23:33:49 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-08-25 16:29:22 +0000

    cxgbe: Deactivate upper layer drivers (like TOE) during detach.
    
    Reviewed by:    np
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D35237
    
    (cherry picked from commit 12b37f8f9c789a48ea0e8cd35f403aee0e020ad9)
---
 sys/dev/cxgbe/t4_main.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 40e2b1b9dbe4..6c1a8162b477 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -859,6 +859,7 @@ static int hold_clip_addr(struct adapter *, struct t4_clip_addr *);
 static int release_clip_addr(struct adapter *, struct t4_clip_addr *);
 #ifdef TCP_OFFLOAD
 static int toe_capability(struct vi_info *, bool);
+static int t4_deactivate_all_uld(struct adapter *);
 static void t4_async_event(struct adapter *);
 #endif
 #ifdef KERN_TLS
@@ -1692,6 +1693,15 @@ t4_detach_common(device_t dev)
 
 	sc = device_get_softc(dev);
 
+#ifdef TCP_OFFLOAD
+	rc = t4_deactivate_all_uld(sc);
+	if (rc) {
+		device_printf(dev,
+		    "failed to detach upper layer drivers: %d\n", rc);
+		return (rc);
+	}
+#endif
+
 	if (sc->cdev) {
 		destroy_dev(sc->cdev);
 		sc->cdev = NULL;
@@ -12624,6 +12634,34 @@ t4_deactivate_uld(struct adapter *sc, int id)
 	return (rc);
 }
 
+static int
+t4_deactivate_all_uld(struct adapter *sc)
+{
+	int rc;
+	struct uld_info *ui;
+
+	rc = begin_synchronized_op(sc, NULL, SLEEP_OK, "t4detuld");
+	if (rc != 0)
+		return (ENXIO);
+
+	sx_slock(&t4_uld_list_lock);
+
+	SLIST_FOREACH(ui, &t4_uld_list, link) {
+		if (isset(&sc->active_ulds, ui->uld_id)) {
+			rc = ui->deactivate(sc);
+			if (rc != 0)
+				break;
+			clrbit(&sc->active_ulds, ui->uld_id);
+			ui->refcount--;
+		}
+	}
+
+	sx_sunlock(&t4_uld_list_lock);
+	end_synchronized_op(sc, 0);
+
+	return (rc);
+}
+
 static void
 t4_async_event(struct adapter *sc)
 {