xref: /freebsd/sys/dev/isci/scil/sati_unmap.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3  *
4  * This file is provided under a dual BSD/GPLv2 license.  When using or
5  * redistributing this file, you may do so under either license.
6  *
7  * GPL LICENSE SUMMARY
8  *
9  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of version 2 of the GNU General Public License as
13  * published by the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23  * The full GNU General Public License is included in this distribution
24  * in the file called LICENSE.GPL.
25  *
26  * BSD LICENSE
27  *
28  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29  * All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  *
35  *   * Redistributions of source code must retain the above copyright
36  *     notice, this list of conditions and the following disclaimer.
37  *   * Redistributions in binary form must reproduce the above copyright
38  *     notice, this list of conditions and the following disclaimer in
39  *     the documentation and/or other materials provided with the
40  *     distribution.
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53  */
54 
55 #include <sys/cdefs.h>
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  */
sati_unmap_calculate_dsm_blocks(SATI_TRANSLATOR_SEQUENCE_T * sequence,U32 dsm_descriptor_count)82 U32 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  */
sati_unmap_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io,U32 sector_count)108 SATI_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  */
sati_unmap_load_next_descriptor(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io)147 SATI_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  */
sati_unmap_get_max_buffer_size_in_blocks(SATI_TRANSLATOR_SEQUENCE_T * sequence)198 U32 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  */
sati_unmap_initial_processing(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)222 SATI_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  */
sati_unmap_process(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)371 SATI_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  */
sati_unmap_terminate(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)496 void 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  */
sati_unmap_translate_command(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)528 SATI_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  */
sati_unmap_translate_response(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)567 SATI_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