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