summaryrefslogtreecommitdiffstats
path: root/sys/dev/mpt/mpt_cam.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/mpt/mpt_cam.c')
-rw-r--r--sys/dev/mpt/mpt_cam.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c
index b5ad94f..d312b67 100644
--- a/sys/dev/mpt/mpt_cam.c
+++ b/sys/dev/mpt/mpt_cam.c
@@ -1279,8 +1279,9 @@ mpt_execute_req_a64(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
char *mpt_off;
union ccb *ccb;
struct mpt_softc *mpt;
- int seg, first_lim;
- uint32_t flags, nxt_off;
+ bus_addr_t chain_list_addr;
+ int first_lim, seg, this_seg_lim;
+ uint32_t addr, cur_off, flags, nxt_off, tf;
void *sglp = NULL;
MSG_REQUEST_HEADER *hdrp;
SGE_SIMPLE64 *se;
@@ -1434,16 +1435,20 @@ bad:
se = (SGE_SIMPLE64 *) sglp;
for (seg = 0; seg < first_lim; seg++, se++, dm_segs++) {
- uint32_t tf;
-
+ tf = flags;
memset(se, 0, sizeof (*se));
+ MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
se->Address.Low = htole32(dm_segs->ds_addr & 0xffffffff);
if (sizeof(bus_addr_t) > 4) {
- se->Address.High =
- htole32(((uint64_t)dm_segs->ds_addr) >> 32);
+ addr = ((uint64_t)dm_segs->ds_addr) >> 32;
+ /* SAS1078 36GB limitation WAR */
+ if (mpt->is_1078 && (((uint64_t)dm_segs->ds_addr +
+ MPI_SGE_LENGTH(se->FlagsLength)) >> 32) == 9) {
+ addr |= (1 << 31);
+ tf |= MPI_SGE_FLAGS_LOCAL_ADDRESS;
+ }
+ se->Address.High = htole32(addr);
}
- MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
- tf = flags;
if (seg == first_lim - 1) {
tf |= MPI_SGE_FLAGS_LAST_ELEMENT;
}
@@ -1468,15 +1473,11 @@ bad:
/*
* Make up the rest of the data segments out of a chain element
- * (contiained in the current request frame) which points to
+ * (contained in the current request frame) which points to
* SIMPLE64 elements in the next request frame, possibly ending
* with *another* chain element (if there's more).
*/
while (seg < nseg) {
- int this_seg_lim;
- uint32_t tf, cur_off;
- bus_addr_t chain_list_addr;
-
/*
* Point to the chain descriptor. Note that the chain
* descriptor is at the end of the *previous* list (whether
@@ -1504,7 +1505,7 @@ bad:
nxt_off += MPT_RQSL(mpt);
/*
- * Now initialized the chain descriptor.
+ * Now initialize the chain descriptor.
*/
memset(ce, 0, sizeof (*ce));
@@ -1554,16 +1555,24 @@ bad:
* set the end of list and end of buffer flags.
*/
while (seg < this_seg_lim) {
+ tf = flags;
memset(se, 0, sizeof (*se));
+ MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
se->Address.Low = htole32(dm_segs->ds_addr &
0xffffffff);
if (sizeof (bus_addr_t) > 4) {
- se->Address.High =
- htole32(((uint64_t)dm_segs->ds_addr) >> 32);
+ addr = ((uint64_t)dm_segs->ds_addr) >> 32;
+ /* SAS1078 36GB limitation WAR */
+ if (mpt->is_1078 &&
+ (((uint64_t)dm_segs->ds_addr +
+ MPI_SGE_LENGTH(se->FlagsLength)) >>
+ 32) == 9) {
+ addr |= (1 << 31);
+ tf |= MPI_SGE_FLAGS_LOCAL_ADDRESS;
+ }
+ se->Address.High = htole32(addr);
}
- MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
- tf = flags;
- if (seg == this_seg_lim - 1) {
+ if (seg == this_seg_lim - 1) {
tf |= MPI_SGE_FLAGS_LAST_ELEMENT;
}
if (seg == nseg - 1) {
@@ -1868,7 +1877,7 @@ bad:
/*
* Make up the rest of the data segments out of a chain element
- * (contiained in the current request frame) which points to
+ * (contained in the current request frame) which points to
* SIMPLE32 elements in the next request frame, possibly ending
* with *another* chain element (if there's more).
*/
@@ -1904,7 +1913,7 @@ bad:
nxt_off += MPT_RQSL(mpt);
/*
- * Now initialized the chain descriptor.
+ * Now initialize the chain descriptor.
*/
memset(ce, 0, sizeof (*ce));
@@ -1958,7 +1967,7 @@ bad:
MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
tf = flags;
- if (seg == this_seg_lim - 1) {
+ if (seg == this_seg_lim - 1) {
tf |= MPI_SGE_FLAGS_LAST_ELEMENT;
}
if (seg == nseg - 1) {
OpenPOWER on IntegriCloud