Author: jimharris
Date: Fri Sep 14 20:05:38 2012
New Revision: 240514
URL: http://svn.freebsd.org/changeset/base/240514

Log:
  isci(4): Fix SCSI/ATA translation for SCSI_WRITE_BUFFER w/ mode==0x7
  (download microcode with offsets, save, and activate).
  
  SATI translation layer was incorrectly using allocation length instead
  of blocks, and was constructing the ATA command incorrectly.
  
  Also change #define to specify that the 512 block size here is
  specific for DOWNLOAD_MICROCODE, and does not relate to the device's
  logical block size.
  
  Submitted by: scottl (with small modifications)
  MFC after: 3 days

Modified:
  head/sys/dev/isci/scil/sati_util.c
  head/sys/dev/isci/scil/sati_write_buffer.c

Modified: head/sys/dev/isci/scil/sati_util.c
==============================================================================
--- head/sys/dev/isci/scil/sati_util.c  Fri Sep 14 19:55:28 2012        
(r240513)
+++ head/sys/dev/isci/scil/sati_util.c  Fri Sep 14 20:05:38 2012        
(r240514)
@@ -1976,6 +1976,8 @@ void sati_ata_download_microcode_constru
 )
 {
    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
+   U32 allocation_blocks = allocation_length >> 9;
+   U32 buffer_blkoffset = buffer_offset >> 9;
 
    sati_set_ata_command(register_fis, ATA_DOWNLOAD_MICROCODE);
    sati_set_ata_features(register_fis, mode);
@@ -1987,9 +1989,10 @@ void sati_ata_download_microcode_constru
    }
    else //mode == 0x03
    {
-      sati_set_ata_sector_count(register_fis, (U8) (allocation_length >> 9));
-      sati_set_ata_lba_low(register_fis, (U8) (allocation_length >> 17));
-      sati_set_ata_lba_high(register_fis, (U8) (buffer_offset >> 9));
+      sati_set_ata_sector_count(register_fis, (U8) (allocation_blocks & 0xff));
+      sati_set_ata_lba_low(register_fis, (U8) ((allocation_blocks >> 8) & 
0xff));
+      sati_set_ata_lba_mid(register_fis, (U8) (buffer_blkoffset & 0xff));
+      sati_set_ata_lba_high(register_fis, (U8) ((buffer_blkoffset >> 8) & 
0xff));
    }
 
    if((allocation_length == 0) && (buffer_offset == 0))

Modified: head/sys/dev/isci/scil/sati_write_buffer.c
==============================================================================
--- head/sys/dev/isci/scil/sati_write_buffer.c  Fri Sep 14 19:55:28 2012        
(r240513)
+++ head/sys/dev/isci/scil/sati_write_buffer.c  Fri Sep 14 20:05:38 2012        
(r240514)
@@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
 #define WRITE_BUFFER_WRITE_DATA              0x02
 #define WRITE_BUFFER_DOWNLOAD_SAVE           0x05
 #define WRITE_BUFFER_OFFSET_DOWNLOAD_SAVE    0x07
-#define BLOCK_SIZE                           512
+#define DOWNLOAD_MICROCODE_BLOCK_SIZE        512
 
 /**
 * @brief This method will translate the SCSI Write Buffer command
@@ -89,6 +89,7 @@ SATI_STATUS sati_write_buffer_translate_
    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
    SATI_STATUS status = SATI_FAILURE;
    U32 allocation_length;
+   U32 allocation_blocks;
    U32 buffer_offset;
 
    allocation_length = ((sati_get_cdb_byte(cdb, 6) << 16) |
@@ -100,11 +101,13 @@ SATI_STATUS sati_write_buffer_translate_
                     (sati_get_cdb_byte(cdb, 5)));
 
    sequence->allocation_length = allocation_length;
+   allocation_blocks = allocation_length / DOWNLOAD_MICROCODE_BLOCK_SIZE;
 
    switch(sati_get_cdb_byte(cdb, 1))
    {
       case WRITE_BUFFER_WRITE_DATA:
-         if((allocation_length == BLOCK_SIZE) && (buffer_offset == 0) &&
+         if((allocation_length == DOWNLOAD_MICROCODE_BLOCK_SIZE) && 
+            (buffer_offset == 0) &&
             (sati_get_cdb_byte(cdb, 2) == 0))
          {
             sati_ata_write_buffer_construct(ata_io, sequence);
@@ -146,8 +149,9 @@ SATI_STATUS sati_write_buffer_translate_
       case WRITE_BUFFER_OFFSET_DOWNLOAD_SAVE:
          if(((allocation_length & 0x000001FF) == 0) && //Bits 08:00 need to be 
zero per SAT2v7
             ((buffer_offset & 0x000001FF) == 0)     &&
-            (allocation_length <= 
sequence->device->max_blocks_per_microcode_command) &&
-            (allocation_length >= 
sequence->device->min_blocks_per_microcode_command))
+            (allocation_blocks <= 
sequence->device->max_blocks_per_microcode_command) &&
+            ((allocation_blocks >= 
sequence->device->min_blocks_per_microcode_command) ||
+            (allocation_length == 0)))
          {
             sati_ata_download_microcode_construct(
                ata_io,
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to