diff options
Diffstat (limited to 'sys/dev/isci/scil/sati_passthrough.c')
-rw-r--r-- | sys/dev/isci/scil/sati_passthrough.c | 49 |
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) ) |