summaryrefslogtreecommitdiffstats
path: root/sys/dev/siis
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-12-29 21:49:11 +0000
committermav <mav@FreeBSD.org>2009-12-29 21:49:11 +0000
commitb8a003ef1beea7446e2328791d40c81ee37e8bb0 (patch)
tree32ab14466948e19fa8f5739f7c13cd7643937144 /sys/dev/siis
parentf590bf3733391efce2c5bc8816d31608a3af6324 (diff)
downloadFreeBSD-src-b8a003ef1beea7446e2328791d40c81ee37e8bb0.zip
FreeBSD-src-b8a003ef1beea7446e2328791d40c81ee37e8bb0.tar.gz
Usually these controllers are able to automatically decode command code to
get required command protocol. But they have no idea about new commands, such as DATA SET MANAGEMENT (TRIM). As soon as this info any way provided by CAM, give controller specific instructions.
Diffstat (limited to 'sys/dev/siis')
-rw-r--r--sys/dev/siis/siis.c26
-rw-r--r--sys/dev/siis/siis.h6
2 files changed, 27 insertions, 5 deletions
diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index e389928..6f693e4 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -1000,13 +1000,29 @@ siis_execute_transaction(struct siis_slot *slot)
ctp->protocol_override = 0;
ctp->transfer_count = 0;
/* Special handling for Soft Reset command. */
- if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
- (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) {
- ctp->control |= htole16(SIIS_PRB_SOFT_RESET);
+ if (ccb->ccb_h.func_code == XPT_ATA_IO) {
+ if (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) {
+ ctp->control |= htole16(SIIS_PRB_SOFT_RESET);
+ } else {
+ ctp->control |= htole16(SIIS_PRB_PROTOCOL_OVERRIDE);
+ if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) {
+ ctp->protocol_override |=
+ htole16(SIIS_PRB_PROTO_NCQ);
+ }
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
+ ctp->protocol_override |=
+ htole16(SIIS_PRB_PROTO_READ);
+ } else
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
+ ctp->protocol_override |=
+ htole16(SIIS_PRB_PROTO_WRITE);
+ }
+ }
} else if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
- if (ccb->ccb_h.flags & CAM_DIR_IN)
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
ctp->control |= htole16(SIIS_PRB_PACKET_READ);
- if (ccb->ccb_h.flags & CAM_DIR_OUT)
+ else
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
ctp->control |= htole16(SIIS_PRB_PACKET_WRITE);
}
/* Setup the FIS for this request */
diff --git a/sys/dev/siis/siis.h b/sys/dev/siis/siis.h
index 2f8c046..f98d204 100644
--- a/sys/dev/siis/siis.h
+++ b/sys/dev/siis/siis.h
@@ -304,6 +304,12 @@ struct siis_cmd {
#define SIIS_PRB_INTERRUPT_MASK 0x0040
#define SIIS_PRB_SOFT_RESET 0x0080
u_int16_t protocol_override;
+#define SIIS_PRB_PROTO_PACKET 0x0001
+#define SIIS_PRB_PROTO_TCQ 0x0002
+#define SIIS_PRB_PROTO_NCQ 0x0004
+#define SIIS_PRB_PROTO_READ 0x0008
+#define SIIS_PRB_PROTO_WRITE 0x0010
+#define SIIS_PRB_PROTO_TRANSPARENT 0x0020
u_int32_t transfer_count;
u_int8_t fis[24];
union {
OpenPOWER on IntegriCloud