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().
This commit is contained in:
Marius Strobl 2021-01-21 23:48:08 +01:00
parent e60a0db3b8
commit 2dcbf0462e

View File

@ -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.