summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>2014-05-08 20:28:22 +0000
committerken <ken@FreeBSD.org>2014-05-08 20:28:22 +0000
commitc75ba560d756292271c4da6aa1e0ba028195b6e0 (patch)
treea1c19ca362701a916b3f7ffda1883cd50d3e65ac
parentcf9c121b0f9e9fa873da451157ff27bd4cc0866b (diff)
downloadFreeBSD-src-c75ba560d756292271c4da6aa1e0ba028195b6e0.zip
FreeBSD-src-c75ba560d756292271c4da6aa1e0ba028195b6e0.tar.gz
Fix TLR (Transport Layer Retry) support in the mps(4) and mpr(4) drivers.
TLR is necessary for reliable communication with SAS tape drives. This was broken by change 246713 in the mps(4) driver. It changed the cm_data field for SCSI I/O requests to point to the CCB instead of the data buffer. So, instead, look at the CCB's data pointer to determine whether or not we're talking to a tape drive. Also, take the residual into account to make sure that we don't go off the end of the request. MFC after: 3 days Sponsored by: Spectra Logic Corporation
-rw-r--r--sys/dev/mpr/mpr_sas.c6
-rw-r--r--sys/dev/mps/mps_sas.c6
2 files changed, 8 insertions, 4 deletions
diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c
index 1a51109..cde0781 100644
--- a/sys/dev/mpr/mpr_sas.c
+++ b/sys/dev/mpr/mpr_sas.c
@@ -2355,8 +2355,9 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
(csio->cdb_io.cdb_bytes[1] & SI_EVPD) &&
(csio->cdb_io.cdb_bytes[2] == SVPD_SUPPORTED_PAGE_LIST) &&
((csio->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) &&
- (csio->data_ptr != NULL) && (((uint8_t *)cm->cm_data)[0] ==
- T_SEQUENTIAL) && (sc->control_TLR) &&
+ (csio->data_ptr != NULL) &&
+ ((csio->data_ptr[0] & 0x1f) == T_SEQUENTIAL) &&
+ (sc->control_TLR) &&
(sc->mapping_table[csio->ccb_h.target_id].device_info &
MPI2_SAS_DEVICE_INFO_SSP_TARGET)) {
vpd_list = (struct scsi_vpd_supported_page_list *)
@@ -2367,6 +2368,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
TLR_on = (u8)MPI2_SCSIIO_CONTROL_TLR_ON;
alloc_len = ((u16)csio->cdb_io.cdb_bytes[3] << 8) +
csio->cdb_io.cdb_bytes[4];
+ alloc_len -= csio->resid;
for (i = 0; i < MIN(vpd_list->length, alloc_len); i++) {
if (vpd_list->list[i] == 0x90) {
*TLR_bits = TLR_on;
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index 3e140ca..de34de0 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -2316,8 +2316,9 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
(csio->cdb_io.cdb_bytes[1] & SI_EVPD) &&
(csio->cdb_io.cdb_bytes[2] == SVPD_SUPPORTED_PAGE_LIST) &&
((csio->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) &&
- (csio->data_ptr != NULL) && (((uint8_t *)cm->cm_data)[0] ==
- T_SEQUENTIAL) && (sc->control_TLR) &&
+ (csio->data_ptr != NULL) &&
+ ((csio->data_ptr[0] & 0x1f) == T_SEQUENTIAL) &&
+ (sc->control_TLR) &&
(sc->mapping_table[csio->ccb_h.target_id].device_info &
MPI2_SAS_DEVICE_INFO_SSP_TARGET)) {
vpd_list = (struct scsi_vpd_supported_page_list *)
@@ -2328,6 +2329,7 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
TLR_on = (u8)MPI2_SCSIIO_CONTROL_TLR_ON;
alloc_len = ((u16)csio->cdb_io.cdb_bytes[3] << 8) +
csio->cdb_io.cdb_bytes[4];
+ alloc_len -= csio->resid;
for (i = 0; i < MIN(vpd_list->length, alloc_len); i++) {
if (vpd_list->list[i] == 0x90) {
*TLR_bits = TLR_on;
OpenPOWER on IntegriCloud