summaryrefslogtreecommitdiffstats
path: root/sys/dev/isci/scil
diff options
context:
space:
mode:
authorjimharris <jimharris@FreeBSD.org>2013-06-26 22:08:45 +0000
committerjimharris <jimharris@FreeBSD.org>2013-06-26 22:08:45 +0000
commit02bac7d9704bfc60277b722c5e4f4b5f6d22444e (patch)
treeea684feb33ee0d0d8acdf5c904f382d1af9df8dd /sys/dev/isci/scil
parente7f9e472fe57a341b8332bd98447ab01e94e65a3 (diff)
downloadFreeBSD-src-02bac7d9704bfc60277b722c5e4f4b5f6d22444e.zip
FreeBSD-src-02bac7d9704bfc60277b722c5e4f4b5f6d22444e.tar.gz
For ATA_PASSTHROUGH commands, pretend isci(4) supports multiword DMA
by treating it as UDMA. This fixes a problem introduced in r249933/r249939, where CAM sends ATA_DSM_TRIM to SATA devices using ATA_PASSTHROUGH_16. scsi_ata_trim() sets protocol as DMA (not UDMA) which is for multi-word DMA, even though no such mode is selected for the device. isci(4) would fail these commands which is the correct behavior but not consistent with other HBAs, namely LSI's. smh@ did some further testing on an LSI controller, which rejected ATA_PASSTHROUGH_16 commands with mode=UDMA_OUT, even though only a UDMA mode was selected on the device. So this precludes adding any kind of mode detection in CAM to determine which mode to use on a per-device basis. Sponsored by: Intel Discussed with: scottl, smh Reported by: scottl Tested by: scottl MFC after: 3 days
Diffstat (limited to 'sys/dev/isci/scil')
-rw-r--r--sys/dev/isci/scil/sati_passthrough.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/sys/dev/isci/scil/sati_passthrough.c b/sys/dev/isci/scil/sati_passthrough.c
index e35b5ea..c2f3941 100644
--- a/sys/dev/isci/scil/sati_passthrough.c
+++ b/sys/dev/isci/scil/sati_passthrough.c
@@ -85,6 +85,7 @@ __FBSDID("$FreeBSD$");
// Protocols
#define PASSTHROUGH_PIO_DATA_IN 0x4
#define PASSTHROUGH_PIO_DATA_OUT 0x5
+#define PASSTHROUGH_DMA 0x6
#define PASSTHROUGH_UDMA_DATA_IN 0xA
#define PASSTHROUGH_UDMA_DATA_OUT 0xB
#define PASSTHROUGH_RETURN_RESPONSE 0xF
@@ -252,8 +253,8 @@ SATI_STATUS sati_passthrough_check_direction(
U8 * cdb
)
{
- if ((PASSTHROUGH_CDB_PROTOCOL(cdb) == PASSTHROUGH_PIO_DATA_IN) ||
- (PASSTHROUGH_CDB_PROTOCOL(cdb) == PASSTHROUGH_UDMA_DATA_IN))
+ if ((sequence->protocol == PASSTHROUGH_PIO_DATA_IN) ||
+ (sequence->protocol == PASSTHROUGH_UDMA_DATA_IN))
{
if (PASSTHROUGH_CDB_T_DIR(cdb) == 0x0)
{
@@ -264,8 +265,8 @@ SATI_STATUS sati_passthrough_check_direction(
sequence->data_direction = SATI_DATA_DIRECTION_IN;
}
}
- else if ((PASSTHROUGH_CDB_PROTOCOL(cdb) == PASSTHROUGH_PIO_DATA_OUT) ||
- (PASSTHROUGH_CDB_PROTOCOL(cdb) == PASSTHROUGH_UDMA_DATA_OUT))
+ else if ((sequence->protocol == PASSTHROUGH_PIO_DATA_OUT) ||
+ (sequence->protocol == PASSTHROUGH_UDMA_DATA_OUT))
{
if (PASSTHROUGH_CDB_T_DIR(cdb) == 0x1)
{
@@ -318,6 +319,26 @@ SATI_STATUS sati_passthrough_12_translate_command(
sequence->protocol = PASSTHROUGH_CDB_PROTOCOL (cdb);
register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
+ /*
+ * CAM will send passthrough commands with protocol set to multiword
+ * DMA even though no multiword DMA mode is selected on the device.
+ * This is because some controllers (LSI) will only accept
+ * ATA_PASSTHROUGH commands with DMA mode - not UDMA_IN/OUT.
+ *
+ * Since isci does not support multiword DMA, fix this up here.
+ */
+ if (sequence->protocol == PASSTHROUGH_DMA)
+ {
+ if (PASSTHROUGH_CDB_T_DIR(cdb) == 0x1)
+ {
+ sequence->protocol = PASSTHROUGH_UDMA_DATA_IN;
+ }
+ else
+ {
+ sequence->protocol = PASSTHROUGH_UDMA_DATA_OUT;
+ }
+ }
+
if (sati_passthrough_check_direction(sequence, cdb) != SATI_COMPLETE
|| sati_passthrough_multiple_count_error(cdb)
)
@@ -376,6 +397,26 @@ SATI_STATUS sati_passthrough_16_translate_command(
sequence->protocol = PASSTHROUGH_CDB_PROTOCOL(cdb);
register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
+ /*
+ * CAM will send passthrough commands with protocol set to multiword
+ * DMA even though no multiword DMA mode is selected on the device.
+ * This is because some controllers (LSI) will only accept
+ * ATA_PASSTHROUGH commands with DMA mode - not UDMA_IN/OUT.
+ *
+ * Since isci does not support multiword DMA, fix this up here.
+ */
+ if (sequence->protocol == PASSTHROUGH_DMA)
+ {
+ if (PASSTHROUGH_CDB_T_DIR(cdb) == 0x1)
+ {
+ sequence->protocol = PASSTHROUGH_UDMA_DATA_IN;
+ }
+ else
+ {
+ sequence->protocol = PASSTHROUGH_UDMA_DATA_OUT;
+ }
+ }
+
if (sati_passthrough_check_direction(sequence, cdb) != SATI_COMPLETE
|| sati_passthrough_multiple_count_error(cdb)
)
OpenPOWER on IntegriCloud