FreeBSD/sys/dev/isci/scil/sati_unmap.c
/**
 * @brief This method will process each unmap sequence.
 *
 * @return Indicate if the translation was successful.
 * @retval SATI_SUCCESS
 */
@brief This method will process each unmap sequence.
@return Indicate if the translation was successful.
@brief This method will process each unmap sequence . @return Indicate if the translation was successful .
SATI_STATUS sati_unmap_process(
   SATI_TRANSLATOR_SEQUENCE_T * sequence,
   void                       * scsi_io,
   void                       * ata_io
)
{
   SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state;
   SATI_LBA dsm_descriptor_lba_count;
   U32 dsm_descriptor;
   U32 dsm_bytes;
   U32 dsm_remainder_bytes;
   U32 dsm_blocks;
   U32 max_dsm_blocks;
   unmap_process_state = &sequence->command_specific_data.unmap_process_state;
   unmap_process_state->current_dsm_descriptor = unmap_process_state->virtual_unmap_buffer;
   dsm_descriptor = 0;
   while ((dsm_descriptor < unmap_process_state->max_lba_range_entries) &&
          (unmap_process_state->current_lba_count > 0)) {
      if (unmap_process_state->current_lba_count > SATI_DSM_MAX_SECTOR_COUNT) {
         dsm_descriptor_lba_count = SATI_DSM_MAX_SECTOR_COUNT;
         unmap_process_state->current_lba_count -= SATI_DSM_MAX_SECTOR_COUNT;
         unmap_process_state->next_lba =
             unmap_process_state->current_lba + SATI_DSM_MAX_SECTOR_COUNT;
      } else {
         dsm_descriptor_lba_count = unmap_process_state->current_lba_count;
         unmap_process_state->current_lba_count = 0;
      }
      ((PTRIM_PAIR)(unmap_process_state->current_dsm_descriptor))->sector_address =
          unmap_process_state->current_lba;
      ((PTRIM_PAIR)(unmap_process_state->current_dsm_descriptor))->sector_count =
          dsm_descriptor_lba_count;
      if (unmap_process_state->current_lba_count == 0) {
         --unmap_process_state->max_unmap_block_descriptors;
         if (unmap_process_state->max_unmap_block_descriptors > 0) {
            sati_unmap_load_next_descriptor(sequence,scsi_io);
         }
      } else {
         unmap_process_state->current_lba = unmap_process_state->next_lba;
      }
      ASSERT(unmap_process_state->current_lba <= SATI_DSM_MAX_SECTOR_ADDRESS);
      dsm_descriptor++;
      unmap_process_state->current_dsm_descriptor =
          (U8 *)(unmap_process_state->current_dsm_descriptor) + sizeof(TRIM_PAIR);
   }
   dsm_blocks     = sati_unmap_calculate_dsm_blocks(sequence,dsm_descriptor);
   dsm_bytes      = dsm_blocks * sequence->device->logical_block_size;
   max_dsm_blocks = sati_unmap_get_max_buffer_size_in_blocks(sequence);
   dsm_remainder_bytes = sequence->device->logical_block_size;
   dsm_remainder_bytes -= (U32)((POINTER_UINT)unmap_process_state->current_dsm_descriptor &
                                (sequence->device->logical_block_size-1));
   if (dsm_remainder_bytes != sequence->device->logical_block_size)
   {
       dsm_remainder_bytes += (sequence->device->logical_block_size * (max_dsm_blocks - dsm_blocks));
       memset((U8 *)unmap_process_state->current_dsm_descriptor, 0, dsm_remainder_bytes);
   }
   sati_cb_sge_write(unmap_process_state->unmap_buffer_sgl_pair,
                     unmap_process_state->physical_unmap_buffer_low,
                     unmap_process_state->physical_unmap_buffer_high,
                     dsm_bytes);
   sati_unmap_construct(sequence,
                        scsi_io,
                        ata_io,
                        dsm_blocks);
   if (unmap_process_state->current_lba_count == 0)
   {
       sequence->state = SATI_SEQUENCE_STATE_FINAL;
   }
   return SATI_SUCCESS_SGL_TRANSLATED;
}
SATI_STATUS sati_unmap_process ( SATI_TRANSLATOR_SEQUENCE_T * sequence , void * scsi_io , void * ata_io ) { SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state ; SATI_LBA dsm_descriptor_lba_count ; U32 dsm_descriptor ; U32 dsm_bytes ; U32 dsm_remainder_bytes ; U32 dsm_blocks ; U32 max_dsm_blocks ; unmap_process_state = & sequence -> command_specific_data . unmap_process_state ; unmap_process_state -> current_dsm_descriptor = unmap_process_state -> virtual_unmap_buffer ; dsm_descriptor = 0 ; while ( ( dsm_descriptor < unmap_process_state -> max_lba_range_entries ) && ( unmap_process_state -> current_lba_count > 0 ) ) { if ( unmap_process_state -> current_lba_count > SATI_DSM_MAX_SECTOR_COUNT ) { dsm_descriptor_lba_count = SATI_DSM_MAX_SECTOR_COUNT ; unmap_process_state -> current_lba_count -= SATI_DSM_MAX_SECTOR_COUNT ; unmap_process_state -> next_lba = unmap_process_state -> current_lba + SATI_DSM_MAX_SECTOR_COUNT ; } else { dsm_descriptor_lba_count = unmap_process_state -> current_lba_count ; unmap_process_state -> current_lba_count = 0 ; } ( ( PTRIM_PAIR ) ( unmap_process_state -> current_dsm_descriptor ) ) -> sector_address = unmap_process_state -> current_lba ; ( ( PTRIM_PAIR ) ( unmap_process_state -> current_dsm_descriptor ) ) -> sector_count = dsm_descriptor_lba_count ; if ( unmap_process_state -> current_lba_count == 0 ) { -- unmap_process_state -> max_unmap_block_descriptors ; if ( unmap_process_state -> max_unmap_block_descriptors > 0 ) { sati_unmap_load_next_descriptor ( sequence , scsi_io ) ; } } else { unmap_process_state -> current_lba = unmap_process_state -> next_lba ; } ASSERT ( unmap_process_state -> current_lba <= SATI_DSM_MAX_SECTOR_ADDRESS ) ; dsm_descriptor ++ ; unmap_process_state -> current_dsm_descriptor = ( U8 * ) ( unmap_process_state -> current_dsm_descriptor ) + sizeof ( TRIM_PAIR ) ; } dsm_blocks = sati_unmap_calculate_dsm_blocks ( sequence , dsm_descriptor ) ; dsm_bytes = dsm_blocks * sequence -> device -> logical_block_size ; max_dsm_blocks = sati_unmap_get_max_buffer_size_in_blocks ( sequence ) ; dsm_remainder_bytes = sequence -> device -> logical_block_size ; dsm_remainder_bytes -= ( U32 ) ( ( POINTER_UINT ) unmap_process_state -> current_dsm_descriptor & ( sequence -> device -> logical_block_size - 1 ) ) ; if ( dsm_remainder_bytes != sequence -> device -> logical_block_size ) { dsm_remainder_bytes += ( sequence -> device -> logical_block_size * ( max_dsm_blocks - dsm_blocks ) ) ; memset ( ( U8 * ) unmap_process_state -> current_dsm_descriptor , 0 , dsm_remainder_bytes ) ; } sati_cb_sge_write ( unmap_process_state -> unmap_buffer_sgl_pair , unmap_process_state -> physical_unmap_buffer_low , unmap_process_state -> physical_unmap_buffer_high , dsm_bytes ) ; sati_unmap_construct ( sequence , scsi_io , ata_io , dsm_blocks ) ; if ( unmap_process_state -> current_lba_count == 0 ) { sequence -> state = SATI_SEQUENCE_STATE_FINAL ; } return SATI_SUCCESS_SGL_TRANSLATED ; }
@brief This method will process each unmap sequence.
@brief This method will process each unmap sequence .
// Set up the starting address of the buffer for this portion of the translation // Translate as much as we can // See if the LBA count will fit in to a single descriptor // Can't fit all of the lbas for this descriptor in to // one DSM request.  Adjust the current LbaCount and total // remaining for the next descriptor // It all fits in to one descriptor // Fill in the ATA DSM descriptor // See if we can move on to the next descriptor // See if there is another descriptor // Move on to the next descriptor // Move to the next LBA in this descriptor // Make sure the LBA does not exceed 48 bits... // Increment the number of descriptors used and point to the next entry // Calculate number of blocks we have filled in // The current_dsm_descriptor points to the next location in the buffer // Get the remaining bytes from the last translated descriptor // to the end of the 4k buffer. // If there was no remainder, the complete buffer was filled in. // Add on the remaining unfilled blocks // According to ATA-8, if the DSM buffer is not completely filled with // valid DSM descriptor data, the remaining portion of the // buffer must be filled in with zeros. // Tell scic to utilize this sgl pair for write DMA processing of // the SCSI UNMAP translation with the total number of bytes for this transfer // Construct the unmap ATA request // Determine sequence next state based on whether there is more translation // to complete // used for completion routine to determine if there is more processing // This requests has already translated the SGL, have SCIC skip SGL translataion