svn commit: r252651 - stable/9/sys/dev/isci/scil

Jim Harris jimharris at FreeBSD.org
Wed Jul 3 23:29:41 UTC 2013


Author: jimharris
Date: Wed Jul  3 23:29:40 2013
New Revision: 252651
URL: http://svnweb.freebsd.org/changeset/base/252651

Log:
  MFC r252262:
  
    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

Modified:
  stable/9/sys/dev/isci/scil/sati_passthrough.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/isci/scil/sati_passthrough.c
==============================================================================
--- stable/9/sys/dev/isci/scil/sati_passthrough.c	Wed Jul  3 23:28:07 2013	(r252650)
+++ stable/9/sys/dev/isci/scil/sati_passthrough.c	Wed Jul  3 23:29:40 2013	(r252651)
@@ -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_direc
    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_direc
          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_translat
    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_translat
    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)
       )


More information about the svn-src-stable-9 mailing list