diff options
author | Scott Long <scottl@FreeBSD.org> | 2018-02-06 06:55:55 +0000 |
---|---|---|
committer | Scott Long <scottl@FreeBSD.org> | 2018-02-06 06:55:55 +0000 |
commit | 4b07a5606c46533ecc9c373d9f4dc534d09a6520 (patch) | |
tree | d8b114f4fd863a4ae761742081b255815da45147 /sys/dev | |
parent | 99e7a4ad9e6fe53868cb15449667ad46814d692b (diff) | |
download | src-4b07a5606c46533ecc9c373d9f4dc534d09a6520.tar.gz src-4b07a5606c46533ecc9c373d9f4dc534d09a6520.zip |
Fix a case where a request frame can be composed that requires 2 or more
SGList elements, but there's only enough space in the request frame for
either 1 element or a chain frame pointer. Previously, the code would
hit the wrong case, add the SGList element, but then fail to add the
chain frame due to lack of space. Re-arrange the code to catch this case
earlier and handle it.
Sponsored by: Netflix
Notes
Notes:
svn path=/head/; revision=328919
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/mps/mps.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/sys/dev/mps/mps.c b/sys/dev/mps/mps.c index 766b77134fe3..b39fa32f7ed0 100644 --- a/sys/dev/mps/mps.c +++ b/sys/dev/mps/mps.c @@ -2609,6 +2609,17 @@ mps_push_sge(struct mps_command *cm, void *sgep, size_t len, int segsleft) if (cm->cm_sglsize < MPS_SGC_SIZE) panic("MPS: Need SGE Error Code\n"); + if (segsleft >= 1 && cm->cm_sglsize < len + MPS_SGC_SIZE) { + /* + * 1 or more segment, enough room for only a chain. + * Hope the previous element wasn't a Simple entry + * that needed to be marked with + * MPI2_SGE_FLAGS_LAST_ELEMENT. Case (4). + */ + if ((error = mps_add_chain(cm)) != 0) + return (error); + } + if (segsleft >= 2 && cm->cm_sglsize < len + MPS_SGC_SIZE + MPS_SGE64_SIZE) { /* @@ -2633,17 +2644,6 @@ mps_push_sge(struct mps_command *cm, void *sgep, size_t len, int segsleft) return (mps_add_chain(cm)); } - if (segsleft >= 1 && cm->cm_sglsize < len + MPS_SGC_SIZE) { - /* - * 1 or more segment, enough room for only a chain. - * Hope the previous element wasn't a Simple entry - * that needed to be marked with - * MPI2_SGE_FLAGS_LAST_ELEMENT. Case (4). - */ - if ((error = mps_add_chain(cm)) != 0) - return (error); - } - #ifdef INVARIANTS /* Case 1: 1 more segment, enough room for it. */ if (segsleft == 1 && cm->cm_sglsize < len) |