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
This commit is contained in:
Jim Harris 2012-09-14 20:05:38 +00:00
parent e87fc7cf7b
commit cc31866200
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=240514
2 changed files with 14 additions and 7 deletions

View File

@ -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))

View File

@ -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,