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:
parent
e60a0db3b8
commit
2dcbf0462e
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user