git: d31b677356d7 - main - ahc(4)/ahd(4): target mode: cancel outstanding AIOs and INOTs

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 23 Apr 2024 21:02:30 UTC
The branch main has been updated by imp:

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

commit d31b677356d74b5747814f98a5151e8ee0595399
Author:     HP van Braam <hp@tmm.cx>
AuthorDate: 2024-04-23 20:47:12 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-04-23 20:57:19 +0000

    ahc(4)/ahd(4): target mode: cancel outstanding AIOs and INOTs
    
    When disabling a lun there can still be outstanding AIOs and INOTs, when
    this happens previously the lun would just fail to disable and trying to
    re-use the lun would break the card.
    
    isp(4) in target mode does the same thing when disabling a lun, in
    testing this allows re-starting of ctld(8) with connected initiators and
    allows initiators to gracefully resume afterwards.
    
    Signed-off-by: HP van Braam <hp@tmm.cx>
    Reviewed by: imp, mav
    Pull Request: https://github.com/freebsd/freebsd-src/pull/1190
---
 sys/dev/aic7xxx/aic79xx.c | 13 +++++++++++--
 sys/dev/aic7xxx/aic7xxx.c | 13 +++++++++++--
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/sys/dev/aic7xxx/aic79xx.c b/sys/dev/aic7xxx/aic79xx.c
index 61e65bf253d7..1b1d31769f90 100644
--- a/sys/dev/aic7xxx/aic79xx.c
+++ b/sys/dev/aic7xxx/aic79xx.c
@@ -9803,6 +9803,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
 	struct	   ahd_tmode_tstate *tstate;
 	struct	   ahd_tmode_lstate *lstate;
 	struct	   ccb_en_lun *cel;
+	union      ccb *cancel_ccb;
 	cam_status status;
 	u_int	   target;
 	u_int	   lun;
@@ -10021,12 +10022,20 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
 
 		if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
 			printf("ATIOs pending\n");
-			ccb->ccb_h.status = CAM_REQ_INVALID;
+			while ((cancel_ccb = (union ccb *)SLIST_FIRST(&lstate->accept_tios)) != NULL) {
+				SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
+				cancel_ccb->ccb_h.status = CAM_REQ_ABORTED;
+				xpt_done(cancel_ccb);
+			};
 		}
 
 		if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
 			printf("INOTs pending\n");
-			ccb->ccb_h.status = CAM_REQ_INVALID;
+			while ((cancel_ccb = (union ccb *)SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
+				SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
+				cancel_ccb->ccb_h.status = CAM_REQ_ABORTED;
+				xpt_done(cancel_ccb);
+			};
 		}
 
 		if (ccb->ccb_h.status != CAM_REQ_CMP) {
diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c
index b59a35ab5667..1560aa4fe312 100644
--- a/sys/dev/aic7xxx/aic7xxx.c
+++ b/sys/dev/aic7xxx/aic7xxx.c
@@ -7253,6 +7253,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
 	struct	   ahc_tmode_tstate *tstate;
 	struct	   ahc_tmode_lstate *lstate;
 	struct	   ccb_en_lun *cel;
+	union      ccb *cancel_ccb;
 	cam_status status;
 	u_int	   target;
 	u_int	   lun;
@@ -7520,12 +7521,20 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
 
 		if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
 			printf("ATIOs pending\n");
-			ccb->ccb_h.status = CAM_REQ_INVALID;
+			while ((cancel_ccb = (union ccb *)SLIST_FIRST(&lstate->accept_tios)) != NULL) {
+				SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
+				cancel_ccb->ccb_h.status = CAM_REQ_ABORTED;
+				xpt_done(cancel_ccb);
+			};
 		}
 
 		if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
 			printf("INOTs pending\n");
-			ccb->ccb_h.status = CAM_REQ_INVALID;
+			while ((cancel_ccb = (union ccb *)SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
+				SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
+				cancel_ccb->ccb_h.status = CAM_REQ_ABORTED;
+				xpt_done(cancel_ccb);
+			};
 		}
 
 		if (ccb->ccb_h.status != CAM_REQ_CMP) {