1/*-
2 * This file is provided under a dual BSD/GPLv2 license.  When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 *   * Redistributions of source code must retain the above copyright
34 *     notice, this list of conditions and the following disclaimer.
35 *   * Redistributions in binary form must reproduce the above copyright
36 *     notice, this list of conditions and the following disclaimer in
37 *     the documentation and/or other materials provided with the
38 *     distribution.
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 */
52
53#include <sys/cdefs.h>
54__FBSDID("$FreeBSD$");
55
56/**
57 * @file
58 * @brief This file contains the method implementations required to
59 *        translate the SCSI unmap command.
60 */
61
62#if !defined(DISABLE_SATI_UNMAP)
63
64#include <dev/isci/scil/sati_unmap.h>
65#include <dev/isci/scil/sati_callbacks.h>
66#include <dev/isci/scil/sati_translator_sequence.h>
67#include <dev/isci/scil/sati_util.h>
68#include <dev/isci/scil/intel_ata.h>
69#include <dev/isci/scil/intel_scsi.h>
70#include <dev/isci/scil/intel_sat.h>
71
72//******************************************************************************
73//* P R I V A T E   M E T H O D S
74//******************************************************************************
75
76/**
77 * @brief This method translates a given number of DSM
78 *        requests into DSM blocks based on the devices logical block size
79 *
80 * @return Number of DSM blocks required for the DSM descriptor count
81 */
82U32 sati_unmap_calculate_dsm_blocks(
83   SATI_TRANSLATOR_SEQUENCE_T * sequence,
84   U32                          dsm_descriptor_count
85)
86{
87   U32 blocks = (dsm_descriptor_count * sizeof(TRIM_PAIR))/sequence->device->logical_block_size;
88   if ((dsm_descriptor_count * sizeof(TRIM_PAIR)) % sequence->device->logical_block_size)
89   {
90       blocks++;
91   }
92   return blocks;
93}
94
95/**
96 * @brief This method performs the SCSI Unmap command translation
97 *        functionality.
98 *        This includes:
99 *        - setting the command register
100 *        - setting the device head register
101 *        - filling in fields in the SATI_TRANSLATOR_SEQUENCE object.
102 *        For more information on the parameters passed to this method,
103 *        please reference sati_translate_command().
104 *
105 * @return Indicate if the method was successfully completed.
106 * @retval SATI_SUCCESS This is returned in all other cases.
107 */
108SATI_STATUS sati_unmap_construct(
109   SATI_TRANSLATOR_SEQUENCE_T * sequence,
110   void                       * scsi_io,
111   void                       * ata_io,
112   U32                          sector_count
113)
114{
115   U8 * h2d_register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
116   U8 * d2h_register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
117
118   sati_set_ata_command(h2d_register_fis, ATA_DATA_SET_MANAGEMENT);
119   sati_set_ata_features(h2d_register_fis, 0x01);
120   sati_set_ata_sector_count(h2d_register_fis, (U8)sector_count);
121   sati_set_ata_device_head(h2d_register_fis, ATA_DEV_HEAD_REG_LBA_MODE_ENABLE);
122
123   // Set the completion status since the core will not do that for
124   // the udma fast path.
125   sati_set_ata_status(d2h_register_fis, 0x00);
126
127   // Set up the direction and protocol for SCIC
128   sequence->data_direction                 = SATI_DATA_DIRECTION_OUT;
129   sequence->protocol                       = SAT_PROTOCOL_UDMA_DATA_OUT;
130   // The UNMAP translation will always require a callback
131   // on every response so it can free memory if an error
132   // occurs.
133   sequence->is_translate_response_required = TRUE;
134
135   ASSERT(sector_count < 0x100);
136
137   return SATI_SUCCESS;
138}
139
140/**
141 * @brief This method updates the unmap sequence state to the next
142 *        unmap descriptor
143 *
144 * @return Indicate if the method was successfully completed.
145 * @retval SATI_SUCCESS This is returned in all other cases.
146 */
147SATI_STATUS sati_unmap_load_next_descriptor(
148   SATI_TRANSLATOR_SEQUENCE_T * sequence,
149   void                       * scsi_io
150)
151{
152   SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state;
153   U32                             index;
154   U8                              unmap_block_descriptor[16];
155
156   unmap_process_state = &sequence->command_specific_data.unmap_process_state;
157
158   // Load the next descriptor
159   for(index = unmap_process_state->current_unmap_block_descriptor_index;
160       index < unmap_process_state->current_unmap_block_descriptor_index +
161               SATI_UNMAP_SIZEOF_SCSI_UNMAP_BLOCK_DESCRIPTOR;
162       index++)
163   {
164      sati_get_data_byte(sequence,
165         scsi_io,
166         index,
167         &unmap_block_descriptor[index-unmap_process_state->current_unmap_block_descriptor_index]);
168   }
169
170   // Update the internal state for the next translation pass
171   unmap_process_state->current_lba_count = (unmap_block_descriptor[8] << 24) |
172                                            (unmap_block_descriptor[9] << 16) |
173                                            (unmap_block_descriptor[10] << 8) |
174                                            (unmap_block_descriptor[11]);
175   unmap_process_state->current_lba       = ((SATI_LBA)(unmap_block_descriptor[0]) << 56) |
176                                            ((SATI_LBA)(unmap_block_descriptor[1]) << 48) |
177                                            ((SATI_LBA)(unmap_block_descriptor[2]) << 40) |
178                                            ((SATI_LBA)(unmap_block_descriptor[3]) << 32) |
179                                            ((SATI_LBA)(unmap_block_descriptor[4]) << 24) |
180                                            ((SATI_LBA)(unmap_block_descriptor[5]) << 16) |
181                                            ((SATI_LBA)(unmap_block_descriptor[6]) << 8) |
182                                            ((SATI_LBA)(unmap_block_descriptor[7]));
183   unmap_process_state->next_lba          = 0;
184
185   // Update the index for the next descriptor to translate
186   unmap_process_state->current_unmap_block_descriptor_index += SATI_UNMAP_SIZEOF_SCSI_UNMAP_BLOCK_DESCRIPTOR;
187
188   return SATI_SUCCESS;
189}
190
191/**
192 * @brief This method determines the max number of blocks of DSM data
193 *        that can be satisfied by the device and the SW
194 *
195 * @return Number of blocks supported
196 * @retval Number of blocks supported
197 */
198U32 sati_unmap_get_max_buffer_size_in_blocks(
199   SATI_TRANSLATOR_SEQUENCE_T * sequence
200)
201{
202   // Currently this SATI implementation only supports a single
203   // 4k block of memory for the DMA write operation for simplicity
204   // (no need to handle more than one SG element).
205   // Since most run time UNMAP requests use 1K or less buffer space,
206   // there is no performance degradation with only supporting a
207   // single physical page.  For best results allocate the maximum
208   // amount of memory the device can handle up to the maximum of 4K.
209   return MIN(SATI_DSM_MAX_BUFFER_SIZE/sequence->device->logical_block_size,
210              sequence->device->max_lba_range_entry_blocks);
211}
212
213/**
214 * @brief This method will be called before starting the first unmap translation
215 *
216 * @return Indicate if the translation was successful.
217 * @retval SATI_SUCCESS This is returned if the command translation was
218 *         successful and no further processing.
219 * @retval SATI_COMPLETE - The initial processing was completed successfully
220 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA - Failed the initial processing
221 */
222SATI_STATUS sati_unmap_initial_processing(
223   SATI_TRANSLATOR_SEQUENCE_T * sequence,
224   void                       * scsi_io,
225   void                       * ata_io
226)
227{
228   SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state;
229   U8 * cdb;
230   U16 unmap_length;
231   U32 descriptor_length;
232   U32 index;
233   U32 max_dsm_blocks;
234   U8  unmap_param_list[8];
235
236   unmap_process_state = &sequence->command_specific_data.unmap_process_state;
237
238   // Set up the sequence type for unmap translation
239   sequence->type = SATI_SEQUENCE_UNMAP;
240
241   // Make sure the device is TRIM capable
242   if ((sequence->device->capabilities & SATI_DEVICE_CAP_DSM_TRIM_SUPPORT)
243       != SATI_DEVICE_CAP_DSM_TRIM_SUPPORT)
244   {
245      // Can't send TRIM request to device that does not support it
246      sati_scsi_sense_data_construct(
247         sequence,
248         scsi_io,
249         SCSI_STATUS_CHECK_CONDITION,
250         SCSI_SENSE_ILLEGAL_REQUEST,
251         SCSI_ASC_INVALID_FIELD_IN_CDB,
252         SCSI_ASCQ_INVALID_FIELD_IN_CDB
253      );
254      return SATI_FAILURE_CHECK_RESPONSE_DATA;
255   }
256
257   // get the amount of data being sent from the cdb
258   cdb = sati_cb_get_cdb_address(scsi_io);
259   unmap_length = (sati_get_cdb_byte(cdb, 7) << 8) | sati_get_cdb_byte(cdb, 8);
260
261   // If nothing has been requested return success now.
262   if (unmap_length == 0)
263   {
264       // SAT: This is not an error
265       return SATI_SUCCESS;
266   }
267   if (unmap_length < SATI_UNMAP_SIZEOF_SCSI_UNMAP_PARAMETER_LIST)
268   {
269      // Not enough length specified in the CDB
270      sati_scsi_sense_data_construct(
271         sequence,
272         scsi_io,
273         SCSI_STATUS_CHECK_CONDITION,
274         SCSI_SENSE_ILLEGAL_REQUEST,
275         SCSI_ASC_INVALID_FIELD_IN_CDB,
276         SCSI_ASCQ_INVALID_FIELD_IN_CDB
277      );
278      return SATI_FAILURE_CHECK_RESPONSE_DATA;
279   }
280
281   sequence->allocation_length = unmap_length;
282
283   // Get the unmap parameter header
284   for(index = 0; index < SATI_UNMAP_SIZEOF_SCSI_UNMAP_PARAMETER_LIST; index++)
285   {
286      sati_get_data_byte(sequence, scsi_io, index,   &unmap_param_list[index]);
287   }
288   descriptor_length = (unmap_param_list[2] << 8) | unmap_param_list[3];
289
290   // Check length again
291   if (descriptor_length == 0)
292   {
293       // SAT: This is not an error
294       return SATI_SUCCESS;
295   }
296
297   if ((U32)(unmap_length - SATI_UNMAP_SIZEOF_SCSI_UNMAP_PARAMETER_LIST) < descriptor_length)
298   {
299      // Not enough length specified in the CDB
300      sati_scsi_sense_data_construct(
301         sequence,
302         scsi_io,
303         SCSI_STATUS_CHECK_CONDITION,
304         SCSI_SENSE_ILLEGAL_REQUEST,
305         SCSI_ASC_INVALID_FIELD_IN_CDB,
306         SCSI_ASCQ_INVALID_FIELD_IN_CDB
307      );
308      return SATI_FAILURE_CHECK_RESPONSE_DATA;
309   }
310
311   // Save the maximum unmap block descriptors in this request
312   unmap_process_state->max_unmap_block_descriptors =
313       descriptor_length/SATI_UNMAP_SIZEOF_SCSI_UNMAP_BLOCK_DESCRIPTOR;
314
315   // Determine the maximum size of the write buffer that will be required
316   // for the translation in terms of number of blocks
317   max_dsm_blocks = sati_unmap_get_max_buffer_size_in_blocks(sequence);
318
319   // Save the maximum number of DSM descriptors we can send during the translation
320   unmap_process_state->max_lba_range_entries =
321       (max_dsm_blocks*sequence->device->logical_block_size)/sizeof(TRIM_PAIR);
322
323   // Get the write buffer for the translation
324   sati_cb_allocate_dma_buffer(
325      scsi_io,
326      max_dsm_blocks*sequence->device->logical_block_size,
327      &(unmap_process_state->virtual_unmap_buffer),
328      &(unmap_process_state->physical_unmap_buffer_low),
329      &(unmap_process_state->physical_unmap_buffer_high));
330
331   // Makes sure we have a buffer
332   if (unmap_process_state->virtual_unmap_buffer == NULL)
333   {
334      // Resource failure
335      sati_scsi_sense_data_construct(
336         sequence,
337         scsi_io,
338         SCSI_STATUS_BUSY,
339         SCSI_SENSE_NO_SENSE,
340         SCSI_ASC_NO_ADDITIONAL_SENSE,
341         SCSI_ASCQ_NO_ADDITIONAL_SENSE
342      );
343      return SATI_FAILURE_CHECK_RESPONSE_DATA;
344   }
345
346   // Get the first SGL entry.  This code will only use one 4K page so will
347   // only utilize the first sge.
348   sati_cb_sgl_next_sge(scsi_io,
349                        ata_io,
350                        NULL,
351                        &(unmap_process_state->unmap_buffer_sgl_pair));
352
353   // Load the first descriptor to start the translation loop
354   unmap_process_state->current_unmap_block_descriptor_index =
355      SATI_UNMAP_SIZEOF_SCSI_UNMAP_PARAMETER_LIST;
356   sati_unmap_load_next_descriptor(sequence,scsi_io);
357
358   // Next state will be incomplete since translation
359   // will require a callback and possibly more requests.
360   sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE;
361
362   return SATI_COMPLETE;
363}
364
365/**
366 * @brief This method will process each unmap sequence.
367 *
368 * @return Indicate if the translation was successful.
369 * @retval SATI_SUCCESS
370 */
371SATI_STATUS sati_unmap_process(
372   SATI_TRANSLATOR_SEQUENCE_T * sequence,
373   void                       * scsi_io,
374   void                       * ata_io
375)
376{
377   SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state;
378   SATI_LBA dsm_descriptor_lba_count;
379   U32 dsm_descriptor;
380   U32 dsm_bytes;
381   U32 dsm_remainder_bytes;
382   U32 dsm_blocks;
383   U32 max_dsm_blocks;
384
385   unmap_process_state = &sequence->command_specific_data.unmap_process_state;
386
387   // Set up the starting address of the buffer for this portion of the translation
388   unmap_process_state->current_dsm_descriptor = unmap_process_state->virtual_unmap_buffer;
389   dsm_descriptor = 0;
390
391   // Translate as much as we can
392   while ((dsm_descriptor < unmap_process_state->max_lba_range_entries) &&
393          (unmap_process_state->current_lba_count > 0)) {
394      // See if the LBA count will fit in to a single descriptor
395      if (unmap_process_state->current_lba_count > SATI_DSM_MAX_SECTOR_COUNT) {
396         // Can't fit all of the lbas for this descriptor in to
397         // one DSM request.  Adjust the current LbaCount and total
398         // remaining for the next descriptor
399         dsm_descriptor_lba_count = SATI_DSM_MAX_SECTOR_COUNT;
400         unmap_process_state->current_lba_count -= SATI_DSM_MAX_SECTOR_COUNT;
401         unmap_process_state->next_lba =
402             unmap_process_state->current_lba + SATI_DSM_MAX_SECTOR_COUNT;
403      } else {
404         // It all fits in to one descriptor
405         dsm_descriptor_lba_count = unmap_process_state->current_lba_count;
406         unmap_process_state->current_lba_count = 0;
407      }
408
409      // Fill in the ATA DSM descriptor
410      ((PTRIM_PAIR)(unmap_process_state->current_dsm_descriptor))->sector_address =
411          unmap_process_state->current_lba;
412      ((PTRIM_PAIR)(unmap_process_state->current_dsm_descriptor))->sector_count =
413          dsm_descriptor_lba_count;
414
415      // See if we can move on to the next descriptor
416      if (unmap_process_state->current_lba_count == 0) {
417         // See if there is another descriptor
418         --unmap_process_state->max_unmap_block_descriptors;
419         if (unmap_process_state->max_unmap_block_descriptors > 0) {
420            // Move on to the next descriptor
421            sati_unmap_load_next_descriptor(sequence,scsi_io);
422         }
423      } else {
424         // Move to the next LBA in this descriptor
425         unmap_process_state->current_lba = unmap_process_state->next_lba;
426      }
427
428      // Make sure the LBA does not exceed 48 bits...
429      ASSERT(unmap_process_state->current_lba <= SATI_DSM_MAX_SECTOR_ADDRESS);
430
431      // Increment the number of descriptors used and point to the next entry
432      dsm_descriptor++;
433      unmap_process_state->current_dsm_descriptor =
434          (U8 *)(unmap_process_state->current_dsm_descriptor) + sizeof(TRIM_PAIR);
435   }
436
437   // Calculate number of blocks we have filled in
438   dsm_blocks     = sati_unmap_calculate_dsm_blocks(sequence,dsm_descriptor);
439   dsm_bytes      = dsm_blocks * sequence->device->logical_block_size;
440   max_dsm_blocks = sati_unmap_get_max_buffer_size_in_blocks(sequence);
441
442   // The current_dsm_descriptor points to the next location in the buffer
443   // Get the remaining bytes from the last translated descriptor
444   // to the end of the 4k buffer.
445   dsm_remainder_bytes = sequence->device->logical_block_size;
446   dsm_remainder_bytes -= (U32)((POINTER_UINT)unmap_process_state->current_dsm_descriptor &
447                                (sequence->device->logical_block_size-1));
448
449   // If there was no remainder, the complete buffer was filled in.
450   if (dsm_remainder_bytes != sequence->device->logical_block_size)
451   {
452       // Add on the remaining unfilled blocks
453       dsm_remainder_bytes += (sequence->device->logical_block_size * (max_dsm_blocks - dsm_blocks));
454
455       // According to ATA-8, if the DSM buffer is not completely filled with
456       // valid DSM descriptor data, the remaining portion of the
457       // buffer must be filled in with zeros.
458       memset((U8 *)unmap_process_state->current_dsm_descriptor, 0, dsm_remainder_bytes);
459   }
460
461   // Tell scic to utilize this sgl pair for write DMA processing of
462   // the SCSI UNMAP translation with the total number of bytes for this transfer
463   sati_cb_sge_write(unmap_process_state->unmap_buffer_sgl_pair,
464                     unmap_process_state->physical_unmap_buffer_low,
465                     unmap_process_state->physical_unmap_buffer_high,
466                     dsm_bytes);
467
468   // Construct the unmap ATA request
469   sati_unmap_construct(sequence,
470                        scsi_io,
471                        ata_io,
472                        dsm_blocks);
473
474   // Determine sequence next state based on whether there is more translation
475   // to complete
476   if (unmap_process_state->current_lba_count == 0)
477   {
478       // used for completion routine to determine if there is more processing
479       sequence->state = SATI_SEQUENCE_STATE_FINAL;
480   }
481   // This requests has already translated the SGL, have SCIC skip SGL translataion
482   return SATI_SUCCESS_SGL_TRANSLATED;
483}
484
485//******************************************************************************
486//* P U B L I C   M E T H O D S
487//******************************************************************************
488
489/**
490 * @brief This method will handle termination of the
491 *        SCSI unmap translation and frees previously allocated
492 *        dma buffer.
493 *
494 * @return None
495 */
496void sati_unmap_terminate(
497   SATI_TRANSLATOR_SEQUENCE_T * sequence,
498   void                       * scsi_io,
499   void                       * ata_io
500)
501{
502   SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state;
503   unmap_process_state = &sequence->command_specific_data.unmap_process_state;
504
505   if (unmap_process_state->virtual_unmap_buffer != NULL)
506   {
507      sati_cb_free_dma_buffer(scsi_io, unmap_process_state->virtual_unmap_buffer);
508      unmap_process_state->virtual_unmap_buffer = NULL;
509   }
510}
511
512/**
513 * @brief This method will translate the SCSI Unmap command
514 *        into corresponding ATA commands.  Depending upon the capabilities
515 *        supported by the target different ATA commands can be selected.
516 *        Additionally, in some cases more than a single ATA command may
517 *        be required.
518 *
519 * @return Indicate if the command translation succeeded.
520 * @retval SATI_SUCCESS This is returned if the command translation was
521 *         successful.
522 * @retval SATI_COMPLETE This is returned if the command translation was
523 *         successful and no ATA commands need to be set.
524 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
525 *         sense data has been created as a result of something specified
526 *         in the parameter data fields.
527 */
528SATI_STATUS sati_unmap_translate_command(
529   SATI_TRANSLATOR_SEQUENCE_T * sequence,
530   void                       * scsi_io,
531   void                       * ata_io
532)
533{
534   SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
535   SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state;
536
537   unmap_process_state = &sequence->command_specific_data.unmap_process_state;
538
539   // Determine if this is the first step in the unmap sequence
540   if ( sequence->state == SATI_SEQUENCE_STATE_INITIAL )
541   {
542       status = sati_unmap_initial_processing(sequence,scsi_io,ata_io);
543       if (status != SATI_COMPLETE)
544       {
545          return status;
546       }
547   }
548   // Translate the next portion of the UNMAP request
549   return sati_unmap_process(sequence, scsi_io, ata_io);
550}
551
552/**
553 * @brief This method will translate the ATA command register FIS
554 *        response into an appropriate SCSI response for Unmap.
555 *        For more information on the parameters passed to this method,
556 *        please reference sati_translate_response().
557 *
558 * @return Indicate if the response translation succeeded.
559 * @retval SATI_SUCCESS This is returned if the command translation was
560 *         successful.
561 * @retval SATI_COMPLETE This is returned if the command translation was
562 *         successful and no ATA commands need to be set.
563 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
564 *         sense data has been created as a result of something specified
565 *         in the parameter data fields.
566 */
567SATI_STATUS sati_unmap_translate_response(
568   SATI_TRANSLATOR_SEQUENCE_T * sequence,
569   void                       * scsi_io,
570   void                       * ata_io
571)
572{
573   U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
574   SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state;
575   SATI_STATUS sati_status = SATI_COMPLETE;
576
577   unmap_process_state = &sequence->command_specific_data.unmap_process_state;
578
579   if (sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT)
580   {
581      sequence->state = SATI_SEQUENCE_STATE_FINAL;
582      sati_scsi_sense_data_construct(
583         sequence,
584         scsi_io,
585         SCSI_STATUS_CHECK_CONDITION,
586         SCSI_SENSE_ABORTED_COMMAND,
587         SCSI_ASC_NO_ADDITIONAL_SENSE,
588         SCSI_ASCQ_NO_ADDITIONAL_SENSE
589      );
590      // All done, terminate the translation
591      sati_unmap_terminate(sequence, scsi_io, ata_io);
592   }
593   else
594   {
595      if (sequence->state != SATI_SEQUENCE_STATE_INCOMPLETE)
596      {
597          // All done, terminate the translation
598          sati_unmap_terminate(sequence, scsi_io, ata_io);
599      }
600      else
601      {
602          // Still translating
603          sati_status = SATI_SEQUENCE_STATE_INCOMPLETE;
604      }
605   }
606   return sati_status;
607}
608
609#endif // !defined(DISABLE_SATI_UNMAP)
610