diff options
author | David Hollister <David.Hollister@Sun.COM> | 2009-12-03 13:34:01 -0700 |
---|---|---|
committer | David Hollister <David.Hollister@Sun.COM> | 2009-12-03 13:34:01 -0700 |
commit | 4b4564630e2553df86b078f1fce1624dade2b2cb (patch) | |
tree | 4ac5c32e222f3465f79814bb37174d67b182deec /usr/src | |
parent | fe199829b492e6b3aa36dd76af597360bb4af121 (diff) | |
download | illumos-joyent-4b4564630e2553df86b078f1fce1624dade2b2cb.tar.gz |
6902289 pmcs is not always setting pkt_resid when needed
Diffstat (limited to 'usr/src')
5 files changed, 73 insertions, 2 deletions
diff --git a/usr/src/cmd/mdb/common/modules/pmcs/pmcs.c b/usr/src/cmd/mdb/common/modules/pmcs/pmcs.c index a54c2e1210..c71328b4b7 100644 --- a/usr/src/cmd/mdb/common/modules/pmcs/pmcs.c +++ b/usr/src/cmd/mdb/common/modules/pmcs/pmcs.c @@ -2197,7 +2197,6 @@ pmcs_help() " -h: Print more detailed hardware information\n" " -i: Print interrupt coalescing information\n" " -I: Print information about each iport\n" - " -l: Dump the trace log (cannot be used with other options)\n" " -p: Print information about each attached PHY\n" " -q: Dump inbound queues\n" " -Q: Dump outbound queues\n" diff --git a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs.conf b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs.conf index b5641a8f4e..e9d116e022 100644 --- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs.conf +++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs.conf @@ -50,7 +50,7 @@ ddi-vhci-class="scsi_vhci"; # 0x0010 - Debug information with regard to discovery/configuration # 0x0020 - Debug information with regard to iport # 0x0040 - Debug information with regard to map -# 0x0080 - Report on SCSI underflow status +# 0x0080 - Report on SCSI underruns and residuals # 0x0100 - Report SCSI status for every command # 0x0200 - PHY lock/unlock debug (very noisy) # 0x0400 - Debug information with regard to device state diff --git a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c index 18dfcdef51..314766e031 100644 --- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c +++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c @@ -1989,11 +1989,43 @@ pmcs_SAS_done(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *msg) pmcs_latch_status(pwp, sp, rptr->status, xd, slen, pptr->path); } else if (rptr->datapres == SAS_RSP_DATAPRES_NO_DATA) { + pmcout_ssp_comp_t *sspcp; + sspcp = (pmcout_ssp_comp_t *)msg; + uint32_t *residp; /* * This is the case for a plain SCSI status. + * Note: If RESC_V is set and we're here, there + * is a residual. We need to find it and update + * the packet accordingly. */ pmcs_latch_status(pwp, sp, rptr->status, NULL, 0, pptr->path); + + if (sspcp->resc_v) { + /* + * Point residual to the SSP_RESP_IU + */ + residp = (uint32_t *)(sspcp + 1); + /* + * param contains the number of bytes + * between where the SSP_RESP_IU may + * or may not be and the residual. + * Increment residp by the appropriate + * number of words: (param+resc_pad)/4). + */ + residp += (LE_32(sspcp->param) + + sspcp->resc_pad) / + sizeof (uint32_t); + pmcs_prt(pwp, PMCS_PRT_DEBUG_UNDERFLOW, + pptr, xp, "%s: tgt 0x%p " + "residual %d for pkt 0x%p", + __func__, (void *) xp, *residp, + (void *) pkt); + ASSERT(LE_32(*residp) <= + pkt->pkt_dma_len); + (void) pmcs_set_resid(pkt, + pkt->pkt_dma_len, LE_32(*residp)); + } } else { pmcs_print_entry(pwp, PMCS_PRT_DEBUG, "illegal SAS response", msg); diff --git a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs.h b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs.h index d9570b1d6d..510c86b75e 100644 --- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs.h +++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs.h @@ -49,6 +49,7 @@ extern "C" { #include <sys/scsi/generic/smp_frames.h> #include <sys/atomic.h> #include <sys/byteorder.h> +#include <sys/sysmacros.h> #include <sys/bitmap.h> #include <sys/queue.h> #include <sys/sdt.h> diff --git a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h index 2ce97c3ae5..5a94277cc2 100644 --- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h +++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h @@ -466,6 +466,45 @@ typedef struct { #define PMCOUT_STATUS_IO_ABORT_IN_PROGRESS 0x40 /* + * IOMB formats + * + * NOTE: All IOMBs are little-endian with exceptions to certain parts of + * some IOMBs. For example, the SSP_RESPONSE_IU in the SSP_COMPLETION + * outbound IOMB is big-endian (SAS). + */ + +/* Common IOMB header */ + +typedef struct pmcs_iomb_header { + uint8_t opcode_lo; + DECL_BITFIELD2(opcode_hi: 4, + cat : 4); + DECL_BITFIELD2(obid : 6, + rsvd1 : 2); + DECL_BITFIELD4(buf_count: 5, + rsvd2 : 1, + h_bit : 1, + v_bit : 1); +} pmcs_iomb_header_t; + +/* PMCOUT_SSP_COMPLETION */ + +typedef struct pmcout_ssp_comp { + pmcs_iomb_header_t header; + uint32_t htag; + uint32_t status; + uint32_t param; + uint16_t ssp_tag; + DECL_BITFIELD3(resc_v : 1, + resc_pad : 2, + rsvd1 : 5); + uint8_t rsvd2; + /* SSP_RESPONSE_IU (if it exists) */ + /* Residual count (if resc_v is set) */ +} pmcout_ssp_comp_t; + + +/* * Device State definitions */ #define PMCS_DEVICE_STATE_NOT_AVAILABLE 0x0 /* Unconfigured tgt */ |