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 __FBSDID("$FreeBSD$");
57
58 /**
59 * @file
60 * @brief This file contains the method definitions to translate
61 * SCSI Log Sense command based of the SATv2 spec.
62 */
63
64 #if !defined(DISABLE_SATI_LOG_SENSE)
65
66 #include <dev/isci/scil/sati_log_sense.h>
67 #include <dev/isci/scil/sati_callbacks.h>
68 #include <dev/isci/scil/sati_util.h>
69
70 //******************************************************************************
71 //* P R I V A T E M E T H O D S
72 //******************************************************************************
73
74 /**
75 * @brief This method constructs the SATI supported log page. This is a log
76 * containing the page codes of all the SATI supported log pages.
77 *
78 * @return n/a
79 *
80 */
81 static
82 void sati_supported_log_page_construct(
83 SATI_TRANSLATOR_SEQUENCE_T * sequence,
84 void * scsi_io
85 )
86 {
87 U32 next_byte;
88 //set SPF = 0 and PAGE_CODE = 0
89 sati_set_data_byte(sequence, scsi_io, 0, 0x00);
90
91 //set SUBPAGE_CODE = 0
92 sati_set_data_byte(sequence, scsi_io, 1, 0x00);
93
94 //set the Page Length to (n-3) or 2 because only two log pages are supported
95 sati_set_data_byte(sequence, scsi_io, 2, 0x00);
96 sati_set_data_byte(sequence, scsi_io, 3, 0x02);
97
98 //specify the next byte to be set
99 next_byte = 4;
100
101 if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SUPPORT)
102 {
103 sati_set_data_byte(
104 sequence,
105 scsi_io,
106 next_byte,
107 SCSI_LOG_PAGE_INFORMATION_EXCEPTION
108 );
109 next_byte = 5;
110 }
111
112 if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SELF_TEST_SUPPORT)
113 {
114 sati_set_data_byte(
115 sequence,
116 scsi_io,
117 next_byte,
118 SCSI_LOG_PAGE_SELF_TEST
119 );
120 }
121 }
122
123 /**
124 * @brief This method sets bytes 4-19 of the self-test log parameter to zero.
125 *
126 * @return n/a
127 *
128 */
129 static
130 void sati_set_parameters_to_zero(
131 SATI_TRANSLATOR_SEQUENCE_T * sequence,
132 void * scsi_io
133 )
134 {
135 sati_set_data_byte(sequence, scsi_io, 8, 0x00); //log_parameter byte 4
136 sati_set_data_byte(sequence, scsi_io, 9, 0x00); //log_parameter byte 5
137 sati_set_data_byte(sequence, scsi_io, 10, 0x00); //log_parameter byte 6
138 sati_set_data_byte(sequence, scsi_io, 11, 0x00); //log_parameter byte 7
139 sati_set_data_byte(sequence, scsi_io, 12, 0x00); //log_parameter byte 8
140 sati_set_data_byte(sequence, scsi_io, 13, 0x00); //log_parameter byte 9
141 sati_set_data_byte(sequence, scsi_io, 14, 0x00); //log_parameter byte 10
142 sati_set_data_byte(sequence, scsi_io, 15, 0x00); //log_parameter byte 11
143 sati_set_data_byte(sequence, scsi_io, 16, 0x00); //log_parameter byte 12
144 sati_set_data_byte(sequence, scsi_io, 17, 0x00); //log_parameter byte 13
145 sati_set_data_byte(sequence, scsi_io, 18, 0x00); //log_parameter byte 14
146 sati_set_data_byte(sequence, scsi_io, 19, 0x00); //log_parameter byte 15
147 sati_set_data_byte(sequence, scsi_io, 20, 0x00); //log_parameter byte 16
148 sati_set_data_byte(sequence, scsi_io, 21, 0x00); //log_parameter byte 17
149 sati_set_data_byte(sequence, scsi_io, 22, 0x00); //log_parameter byte 18
150 sati_set_data_byte(sequence, scsi_io, 23, 0x00); //log_parameter byte 19
151 }
152
153 /**
154 * @brief This method translates the ATA Extended SMART self-test log into
155 * SCSI Sense Key, Additional Sense Code, and Additional Sense code
156 * qualifiers based on the self test status byte in the appropriate
157 * descriptor entry.
158 *
159 * @return n/a
160 *
161 */
162 static
163 void sati_translate_sense_values(
164 SATI_TRANSLATOR_SEQUENCE_T * sequence,
165 void * scsi_io,
166 U8 self_test_status_byte
167 )
168 {
169 //byte 17
170 sati_set_data_byte(
171 sequence,
172 scsi_io,
173 21,
174 SCSI_DIAGNOSTIC_FAILURE_ON_COMPONENT
175 );
176
177 switch(self_test_status_byte)
178 {
179 case 1:
180 //byte 16
181 sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_ABORTED_COMMAND);
182
183 //byte 18
184 sati_set_data_byte(sequence, scsi_io, 22, 0x81);
185 break;
186
187 case 2:
188 //byte 16
189 sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_ABORTED_COMMAND);
190
191 //byte 18
192 sati_set_data_byte(sequence, scsi_io, 22, 0x82);
193 break;
194
195 case 3:
196 //byte 16
197 sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_ABORTED_COMMAND);
198
199 //byte 18
200 sati_set_data_byte(sequence, scsi_io, 22, 0x83);
201 break;
202
203 case 4:
204 //byte 16
205 sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR);
206
207 //byte 18
208 sati_set_data_byte(sequence, scsi_io, 22, 0x84);
209 break;
210
211 case 5:
212 //byte 16
213 sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR);
214
215 //byte 18
216 sati_set_data_byte(sequence, scsi_io, 22, 0x85);
217 break;
218
219 case 6:
220 //byte 16
221 sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR);
222
223 //byte 18
224 sati_set_data_byte(sequence, scsi_io, 22, 0x86);
225 break;
226
227 case 7:
228 //byte 16
229 sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_MEDIUM_ERROR);
230
231 //byte 18
232 sati_set_data_byte(sequence, scsi_io, 22, 0x87);
233 break;
234
235 case 8:
236 //byte 16
237 sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR);
238
239 //byte 18
240 sati_set_data_byte(sequence, scsi_io, 22, 0x88);
241 break;
242
243 default:
244 //byte 16
245 sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_NO_SENSE);
246 //byte 17
247 sati_set_data_byte(sequence, scsi_io, 21, SCSI_ASC_NO_ADDITIONAL_SENSE);
248 //byte 18
249 sati_set_data_byte(sequence, scsi_io, 22, 0x00);
250 break;
251 }
252
253 }
254
255 /**
256 * @brief This method retrieves the correct self-test results by checking the
257 * descriptor index in the extended SMART self-test log. The index is
258 * used to determine the appropriate descriptor entry.
259 *
260 * @return n/a
261 *
262 */
263 static
264 void sati_get_self_test_results(
265 SATI_TRANSLATOR_SEQUENCE_T * sequence,
266 void * scsi_io,
267 ATA_EXTENDED_SMART_SELF_TEST_LOG_T * ata_log
268 )
269 {
270 U16 descriptor_index = *((U16 *)(&ata_log->self_test_descriptor_index[0]));
271
272 /*
273 * SATv2 wants data from descriptor N where N is equal to
274 * (descriptor_index - parameter_code) + 1. Since parameter
275 * code is always 0x0001 just checking descriptor_index.
276 */
277
278 if(descriptor_index <= 0)
279 {
280 sati_set_parameters_to_zero(sequence, scsi_io);
281 }
282 else
283 {
284 sati_set_data_byte(
285 sequence,
286 scsi_io,
287 8,
288 ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.status_byte
289 );
290
291 //Sef-test number unspecified per satv2
292 sati_set_data_byte(sequence, scsi_io, 9, 0x00);
293 sati_set_data_byte(
294 sequence,
295 scsi_io,
296 10,
297 ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.time_stamp_high
298 );
299
300 sati_set_data_byte(
301 sequence,
302 scsi_io,
303 11,
304 ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.time_stamp_low
305 );
306
307 //set to zero because it's a 48bit address
308 sati_set_data_byte(sequence, scsi_io, 12, 0x00);
309 sati_set_data_byte(sequence, scsi_io, 13, 0x00);
310
311 sati_set_data_byte(
312 sequence,
313 scsi_io,
314 14,
315 ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_high_ext
316 );
317
318 sati_set_data_byte(
319 sequence,
320 scsi_io,
321 15,
322 ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_mid_ext
323 );
324
325 sati_set_data_byte(
326 sequence,
327 scsi_io,
328 16,
329 ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_low_ext
330 );
331
332 sati_set_data_byte(
333 sequence,
334 scsi_io,
335 17,
336 ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_high
337 );
338
339 sati_set_data_byte(
340 sequence,
341 scsi_io,
342 18,
343 ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_mid
344 );
345
346 sati_set_data_byte(
347 sequence,
348 scsi_io,
349 19,
350 ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_low
351 );
352
353 sati_translate_sense_values(
354 sequence,
355 scsi_io,
356 ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.status_byte
357 );
358 }
359 }
360
361 /**
362 * @brief This method will construct the first eight bytes of the SCSI self test
363 * log page for both cases when SATI sends a ATA read log ext and a smart
364 * read log command.
365 *
366 * @return n/a
367 *
368 */
369 static
370 void sati_self_test_log_header_construct(
371 SATI_TRANSLATOR_SEQUENCE_T * sequence,
372 void * scsi_io
373 )
374 {
375 //PAGE CODE for Self-Test Log Page
376 sati_set_data_byte(sequence, scsi_io, 0, 0x10);
377 sati_set_data_byte(sequence, scsi_io, 1, 0x00);
378
379 //PAGE LENGTH is 0x14 instead of 0x190, not returning 20/0x190 log perameters
380 sati_set_data_byte(sequence, scsi_io, 2, 0x00);
381 sati_set_data_byte(sequence, scsi_io, 3, 0x14);
382
383 /*
384 * Log PARAMETER 0x0001
385 * Only sending one log parameter per self-test request.
386 */
387 sati_set_data_byte(sequence, scsi_io, 4, 0x00); //log_parameter byte 0
388 sati_set_data_byte(sequence, scsi_io, 5, 0x01); //log_parameter byte 1
389
390 //Set to 0x03 per SATv2 spec
391 sati_set_data_byte(sequence, scsi_io, 6, 0x03); //log_parameter byte 2
392
393 //Parameter Length set to 0x10 per SATv2 spec
394 sati_set_data_byte(sequence, scsi_io, 7, 0x10); //log_parameter byte 3
395 }
396
397 /**
398 * @brief This method will construct the SCSI self test log page from
399 * the Extended SMART self-test log response received from the
400 * ATA device. The response is from a ATA_Read_Log_EXT command
401 * issued by SATI.
402 *
403 * @return n/a
404 *
405 */
406 static
407 void sati_extended_self_test_log_page_construct(
408 SATI_TRANSLATOR_SEQUENCE_T * sequence,
409 void * scsi_io,
410 void * ata_data
411 )
412 {
413 ATA_EXTENDED_SMART_SELF_TEST_LOG_T * ata_log =
414 (ATA_EXTENDED_SMART_SELF_TEST_LOG_T*) ata_data;
415
416 sati_self_test_log_header_construct(sequence, scsi_io);
417
418 //bytes 4-19
419 if( (ata_log->self_test_descriptor_index[0] == 0) &&
420 (ata_log->self_test_descriptor_index[1] == 0))
421 {
422 sati_set_parameters_to_zero(sequence, scsi_io);
423 }
424 else
425 {
426 sati_get_self_test_results(sequence, scsi_io, ata_log);
427 }
428 }
429
430 /**
431 * @brief This method will construct the SCSI self test log page from
432 * the SMART self-test log response received from the ATA device.
433 * The response is from a ATA_SMART_Read_Log command issued by SATI.
434 *
435 * @return n/a
436 *
437 */
438 static
439 void sati_self_test_log_page_construct(
440 SATI_TRANSLATOR_SEQUENCE_T * sequence,
441 void * scsi_io,
442 void * ata_data
443 )
444 {
445 ATA_SMART_SELF_TEST_LOG_T * ata_log =
446 (ATA_SMART_SELF_TEST_LOG_T*) ata_data;
447
448 sati_self_test_log_header_construct(sequence, scsi_io);
449
450 //first descriptor entry(index == 0) is always used because scsi_parameter_code == 1
451 sati_set_data_byte(
452 sequence,
453 scsi_io,
454 8,
455 ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.status_byte
456 );
457
458 //Sef-test number unspecified per satv2
459 sati_set_data_byte(sequence, scsi_io, 9, 0x00);
460
461 sati_set_data_byte(
462 sequence,
463 scsi_io,
464 10,
465 ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.time_stamp_high
466 );
467
468 sati_set_data_byte(
469 sequence,
470 scsi_io,
471 11,
472 ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.time_stamp_low
473 );
474
475 //set to zero because it's a 28bit address
476 sati_set_data_byte(sequence, scsi_io, 12, 0x00);
477 sati_set_data_byte(sequence, scsi_io, 13, 0x00);
478 sati_set_data_byte(sequence, scsi_io, 14, 0x00);
479 sati_set_data_byte(sequence, scsi_io, 15, 0x00);
480
481 sati_set_data_byte(
482 sequence,
483 scsi_io,
484 16,
485 ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_low_ext
486 );
487
488 sati_set_data_byte(
489 sequence,
490 scsi_io,
491 17,
492 ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_high
493 );
494
495 sati_set_data_byte(
496 sequence,
497 scsi_io,
498 18,
499 ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_mid
500 );
501
502 sati_set_data_byte(
503 sequence,
504 scsi_io,
505 19,
506 ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_low
507 );
508
509 sati_translate_sense_values(
510 sequence,
511 scsi_io,
512 ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.status_byte
513 );
514 }
515
516 /**
517 * @brief This method will construct the SCSI information exception log page from
518 * the ATA SMART response received from the ATA device. The response is
519 * from a ATA SMART return status command issued by SATI.
520 *
521 * @return n/a
522 *
523 */
524 static
525 void sati_information_exception_log_page_contruct(
526 SATI_TRANSLATOR_SEQUENCE_T * sequence,
527 void * scsi_io,
528 void * ata_io
529 )
530 {
531 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
532 U32 mid_register = sati_get_ata_lba_mid(register_fis);
533 U32 high_register = sati_get_ata_lba_high(register_fis);
534
535 //Information Exception Page code
536 sati_set_data_byte(
537 sequence,
538 scsi_io,
539 0,
540 SCSI_LOG_PAGE_INFORMATION_EXCEPTION
541 );
542
543 //Sub-page code
544 sati_set_data_byte(sequence, scsi_io, 1, 0x00);
545
546 //Page length of log parameters
547 sati_set_data_byte(sequence, scsi_io, 2, 0x00);
548 sati_set_data_byte(sequence, scsi_io, 3, 0x08);
549
550 //parameter code
551 sati_set_data_byte(sequence, scsi_io, 4, 0x00);
552 sati_set_data_byte(sequence, scsi_io, 5, 0x00);
553
554 //Format and Linking
555 sati_set_data_byte(sequence, scsi_io, 6, 0x03);
556 //Parameter Length
557 sati_set_data_byte(sequence, scsi_io, 7, 0x04);
558
559 if(mid_register == ATA_MID_REGISTER_THRESHOLD_EXCEEDED
560 && high_register == ATA_HIGH_REGISTER_THRESHOLD_EXCEEDED)
561 {
562 sati_set_data_byte(
563 sequence,
564 scsi_io,
565 8,
566 SCSI_ASC_HARDWARE_IMPENDING_FAILURE
567 );
568
569 sati_set_data_byte(
570 sequence,
571 scsi_io,
572 9,
573 SCSI_ASCQ_GENERAL_HARD_DRIVE_FAILURE
574 );
575 }
576 else
577 {
578 sati_set_data_byte(sequence, scsi_io, 8, SCSI_ASC_NO_ADDITIONAL_SENSE);
579 sati_set_data_byte(sequence, scsi_io, 9, SCSI_ASCQ_NO_ADDITIONAL_SENSE);
580 }
581 //setting most recent temperature reading to 0xFF(not supported) for now.
582 sati_set_data_byte(sequence, scsi_io, 10, 0xFF);
583 }
584
585 //******************************************************************************
586 //* P U B L I C M E T H O D S
587 //******************************************************************************
588
589 /**
590 * @brief This method will translate the SCSI Log Sense command into ATA commands
591 * specified by SATv2. ATA commands Read Log EXT and SMART Read Log will
592 * be issued by this translation.
593 *
594 * @return SATI_STATUS Indicates if the command translation succeeded.
595 *
596 */
597 SATI_STATUS sati_log_sense_translate_command(
598 SATI_TRANSLATOR_SEQUENCE_T * sequence,
599 void * scsi_io,
600 void * ata_io
601 )
602 {
603 U8 * cdb = sati_cb_get_cdb_address(scsi_io);
604 SATI_STATUS status = SATI_FAILURE;
605
606 if(SATI_LOG_SENSE_GET_PC_FIELD(cdb) == 1 &&
607 (sati_get_cdb_byte(cdb, 3) == 0))
608 {
609 sequence->allocation_length = (sati_get_cdb_byte(cdb, 7) << 8) |
610 (sati_get_cdb_byte(cdb, 8));
611
612 switch(SATI_LOG_SENSE_GET_PAGE_CODE(cdb))
613 {
614 //Return Supported Log Pages log page
615 case SCSI_LOG_PAGE_SUPPORTED_PAGES :
616 sati_supported_log_page_construct(sequence, scsi_io);
617 sequence->type = SATI_SEQUENCE_LOG_SENSE_SUPPORTED_LOG_PAGE;
618 status = SATI_COMPLETE;
619 break;
620
621 //Return Self-Test Results log page
622 case SCSI_LOG_PAGE_SELF_TEST :
623
624 if((sequence->device->capabilities &
625 SATI_DEVICE_CAP_SMART_SELF_TEST_SUPPORT) == 0)
626 {
627 sati_scsi_sense_data_construct(
628 sequence,
629 scsi_io,
630 SCSI_STATUS_CHECK_CONDITION,
631 SCSI_SENSE_ILLEGAL_REQUEST,
632 SCSI_ASC_INVALID_FIELD_IN_CDB,
633 SCSI_ASCQ_INVALID_FIELD_IN_CDB
634 );
635 status = SATI_FAILURE_CHECK_RESPONSE_DATA;
636 }
637 else
638 {
639 //check if 48-bit Address feature set is supported
640 if((sequence->device->capabilities &
641 SATI_DEVICE_CAP_48BIT_ENABLE))
642 {
643 //ATA Read Log Ext with log address set to 0x07
644 sati_ata_read_log_ext_construct(
645 ata_io,
646 sequence,
647 ATA_LOG_PAGE_EXTENDED_SMART_SELF_TEST,
648 sizeof(ATA_EXTENDED_SMART_SELF_TEST_LOG_T)
649 );
650 sequence->type =
651 SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE;
652 status = SATI_SUCCESS;
653 }
654 else
655 {
656 //ATA Smart Read Log with log address set to 0x06
657 sati_ata_smart_read_log_construct(
658 ata_io,
659 sequence,
660 ATA_LOG_PAGE_SMART_SELF_TEST,
661 sizeof(ATA_SMART_SELF_TEST_LOG_T)
662 );
663 sequence->type = SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE;
664 status = SATI_SUCCESS;
665 }
666 }
667 break;
668
669 //Return Informational Exceptions log page
670 case SCSI_LOG_PAGE_INFORMATION_EXCEPTION :
671 if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SUPPORT)
672 {
673 if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_ENABLE)
674 {
675 sati_ata_smart_return_status_construct(
676 ata_io,
677 sequence,
678 ATA_SMART_SUB_CMD_RETURN_STATUS
679 );
680 sequence->type =
681 SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE;
682 status = SATI_SUCCESS;
683 }
684 else
685 {
686 sati_scsi_sense_data_construct(
687 sequence,
688 scsi_io,
689 SCSI_STATUS_CHECK_CONDITION,
690 SCSI_SENSE_ABORTED_COMMAND,
691 SCSI_ASC_ATA_DEVICE_FEATURE_NOT_ENABLED,
692 SCSI_ASCQ_ATA_DEVICE_FEATURE_NOT_ENABLED
693 );
694
695 status = SATI_FAILURE_CHECK_RESPONSE_DATA;
696 }
697 }
698 else
699 {
700 sati_scsi_sense_data_construct(
701 sequence,
702 scsi_io,
703 SCSI_STATUS_CHECK_CONDITION,
704 SCSI_SENSE_ILLEGAL_REQUEST,
705 SCSI_ASC_INVALID_FIELD_IN_CDB,
706 SCSI_ASCQ_INVALID_FIELD_IN_CDB
707 );
708
709 status = SATI_FAILURE_CHECK_RESPONSE_DATA;
710 }
711 break;
712 default :
713 //UNSPECIFIED SATv2r9
714 sati_scsi_sense_data_construct(
715 sequence,
716 scsi_io,
717 SCSI_STATUS_CHECK_CONDITION,
718 SCSI_SENSE_ILLEGAL_REQUEST,
719 SCSI_ASC_NO_ADDITIONAL_SENSE ,
720 SCSI_ASCQ_NO_ADDITIONAL_SENSE
721 );
722 status = SATI_FAILURE_CHECK_RESPONSE_DATA;
723 break;
724 }
725 }
726 return status;
727 }
728
729 /**
730 * @brief This method will translate the response to the SATI Log Sense
731 * translation. ATA command responses will be translated into the
732 * correct SCSI log pages to be returned by SATI.
733 *
734 * @return SATI_STATUS Indicates if the response translation succeeded.
735 *
736 */
737 SATI_STATUS sati_log_sense_translate_response(
738 SATI_TRANSLATOR_SEQUENCE_T * sequence,
739 void * scsi_io,
740 void * ata_io
741 )
742 {
743 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
744 SATI_STATUS status = SATI_FAILURE;
745
746 if(sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT)
747 {
748 sati_scsi_sense_data_construct(
749 sequence,
750 scsi_io,
751 SCSI_STATUS_CHECK_CONDITION,
752 SCSI_SENSE_ABORTED_COMMAND,
753 SCSI_ASC_NO_ADDITIONAL_SENSE ,
754 SCSI_ASCQ_NO_ADDITIONAL_SENSE
755 );
756 status = SATI_FAILURE_CHECK_RESPONSE_DATA;
757 }
758 else
759 {
760
761 void * ata_data = sati_cb_get_ata_data_address(ata_io);
762
763 if(ata_data == NULL)
764 {
765 return SATI_FAILURE;
766 }
767
768 switch(sequence->type)
769 {
770 case SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE:
771 sati_extended_self_test_log_page_construct(
772 sequence, scsi_io, ata_data
773 );
774
775 status = SATI_COMPLETE;
776 break;
777
778 case SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE:
779 sati_self_test_log_page_construct(sequence, scsi_io, ata_data);
780 status = SATI_COMPLETE;
781 break;
782
783 case SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE:
784 //This function needs a d->h register fis, not ata data
785 sati_information_exception_log_page_contruct(
786 sequence, scsi_io, ata_io
787 );
788
789 status = SATI_COMPLETE;
790 break;
791
792 default:
793 sati_scsi_sense_data_construct(
794 sequence,
795 scsi_io,
796 SCSI_STATUS_CHECK_CONDITION,
797 SCSI_SENSE_ABORTED_COMMAND,
798 SCSI_ASC_NO_ADDITIONAL_SENSE ,
799 SCSI_ASCQ_NO_ADDITIONAL_SENSE
800 );
801 status = SATI_FAILURE_CHECK_RESPONSE_DATA;
802 break;
803 }
804 }
805 return status;
806 }
807
808 #endif // !defined(DISABLE_SATI_LOG_SENSE)
809
Cache object: e686d97590b2fb4a72404b768bfa6443
|