From ae8b353ca4b3e368f293d38074f3fa83354fbfe9 Mon Sep 17 00:00:00 2001 From: jimharris Date: Mon, 17 Sep 2012 16:39:32 +0000 Subject: [PATCH] MFC r240514: 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. Approved by: re (kib) git-svn-id: svn://svn.freebsd.org/base/releng/9.1@240614 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/dev/isci/scil/sati_util.c | 9 ++++++--- sys/dev/isci/scil/sati_write_buffer.c | 12 ++++++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/sys/dev/isci/scil/sati_util.c b/sys/dev/isci/scil/sati_util.c index a161c58c..18c10c82 100644 --- a/sys/dev/isci/scil/sati_util.c +++ b/sys/dev/isci/scil/sati_util.c @@ -1976,6 +1976,8 @@ void sati_ata_download_microcode_construct( ) { 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_construct( } 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)) diff --git a/sys/dev/isci/scil/sati_write_buffer.c b/sys/dev/isci/scil/sati_write_buffer.c index 97bdb74a..dfa4e292 100644 --- a/sys/dev/isci/scil/sati_write_buffer.c +++ b/sys/dev/isci/scil/sati_write_buffer.c @@ -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_command( 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_command( (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_command( 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, -- 2.42.0