aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Strobl <marius@FreeBSD.org>2021-01-21 22:48:08 +0000
committerMarius Strobl <marius@FreeBSD.org>2021-01-21 23:18:39 +0000
commit2dcbf0462e17db1b0a8cc99d1f95a7b0ba6437b2 (patch)
treeb9199b727213d4fc8fd203ad83c275a3101e1300
parente60a0db3b8c922f9bcd085f737508a9cb4eb7f29 (diff)
downloadsrc-2dcbf0462e17db1b0a8cc99d1f95a7b0ba6437b2.tar.gz
src-2dcbf0462e17db1b0a8cc99d1f95a7b0ba6437b2.zip
sym(4): handle mixed tagged/untagged commands gracefully
Handle the case of a tagged command arriving when there's an untagged one still outstanding gracefully instead of panicing. While at it: - Replace fancy arithmetics with a simple assignment as busy_itl can only ever be either 0 or 1. - Fix a comment typo in sym_free_ccb().
-rw-r--r--sys/dev/sym/sym_hipd.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/sys/dev/sym/sym_hipd.c b/sys/dev/sym/sym_hipd.c
index f1c058f75c52..61104f75fd92 100644
--- a/sys/dev/sym/sym_hipd.c
+++ b/sys/dev/sym/sym_hipd.c
@@ -6291,13 +6291,12 @@ static ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order)
goto out_free;
} else {
/*
- * If we have been asked for a tagged command.
+ * If we have been asked for a tagged command, refuse
+ * to overlap with an existing untagged one.
*/
if (tag_order) {
- /*
- * Debugging purpose.
- */
- assert(lp->busy_itl == 0);
+ if (lp->busy_itl != 0)
+ goto out_free;
/*
* Allocate resources for tags if not yet.
*/
@@ -6330,22 +6329,17 @@ static ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order)
* one, refuse to overlap this untagged one.
*/
else {
- /*
- * Debugging purpose.
- */
- assert(lp->busy_itl == 0 && lp->busy_itlq == 0);
+ if (lp->busy_itlq != 0 || lp->busy_itl != 0)
+ goto out_free;
/*
* Count this nexus for this LUN.
* Set up the CCB bus address for reselection.
* Toggle reselect path to untagged.
*/
- if (++lp->busy_itl == 1) {
- lp->head.itl_task_sa = cpu_to_scr(cp->ccb_ba);
- lp->head.resel_sa =
- cpu_to_scr(SCRIPTA_BA (np, resel_no_tag));
- }
- else
- goto out_free;
+ lp->busy_itl = 1;
+ lp->head.itl_task_sa = cpu_to_scr(cp->ccb_ba);
+ lp->head.resel_sa =
+ cpu_to_scr(SCRIPTA_BA (np, resel_no_tag));
}
}
/*
@@ -6391,7 +6385,7 @@ static void sym_free_ccb(hcb_p np, ccb_p cp)
*/
if (lp) {
/*
- * If tagged, release the tag, set the relect path
+ * If tagged, release the tag, set the reselect path.
*/
if (cp->tag != NO_TAG) {
/*
@@ -6412,7 +6406,7 @@ static void sym_free_ccb(hcb_p np, ccb_p cp)
* and uncount this CCB.
*/
lp->head.itl_task_sa = cpu_to_scr(np->bad_itl_ba);
- --lp->busy_itl;
+ lp->busy_itl = 0;
}
/*
* If no JOB active, make the LUN reselect path invalid.