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 test unit ready command.
60 */
61
62#if !defined(DISABLE_SATI_TEST_UNIT_READY)
63
64#include <dev/isci/scil/sati_test_unit_ready.h>
65#include <dev/isci/scil/sati_util.h>
66#include <dev/isci/scil/sati_callbacks.h>
67#include <dev/isci/scil/intel_ata.h>
68#include <dev/isci/scil/intel_scsi.h>
69
70/**
71 * @brief This method will translate the test unit ready SCSI command into
72 *        an ATA CHECK POWER MODE command.
73 *        For more information on the parameters passed to this method,
74 *        please reference sati_translate_command().
75 *
76 * @return Indicate if the command translation succeeded.
77 * @retval SCI_SUCCESS This is returned if the command translation was
78 *         successful.
79 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if the
80 *         LBA field is not 0, the PMI bit is not 0.
81 */
82SATI_STATUS sati_test_unit_ready_translate_command(
83   SATI_TRANSLATOR_SEQUENCE_T * sequence,
84   void                       * scsi_io,
85   void                       * ata_io
86)
87{
88   /**
89    * SAT dictates:
90    * - the device should be in a state to receive commands
91    * - a stopped device should cause sense data.
92    * - a format unit in progresss should cause sense data.
93    * - a self-test in progress should cause sense data.
94    * - a device fault occurred on previous request should cause sense data.
95    * - handling the removable media feature set isn't supported according to
96    *   SAT specifications.
97    */
98   if (sequence->device->state == SATI_DEVICE_STATE_STOPPED)
99   {
100      sati_scsi_sense_data_construct(
101         sequence,
102         scsi_io,
103         SCSI_STATUS_CHECK_CONDITION,
104         SCSI_SENSE_NOT_READY,
105         SCSI_ASC_INITIALIZING_COMMAND_REQUIRED,
106         SCSI_ASCQ_INITIALIZING_COMMAND_REQUIRED
107      );
108      return SATI_FAILURE_CHECK_RESPONSE_DATA;
109   }
110   else if (sequence->device->state
111            == SATI_DEVICE_STATE_SELF_TEST_IN_PROGRESS)
112   {
113      sati_scsi_sense_data_construct(
114         sequence,
115         scsi_io,
116         SCSI_STATUS_CHECK_CONDITION,
117         SCSI_SENSE_NOT_READY,
118         SCSI_ASC_LUN_SELF_TEST_IN_PROGRESS,
119         SCSI_ASCQ_LUN_SELF_TEST_IN_PROGRESS
120      );
121      return SATI_FAILURE_CHECK_RESPONSE_DATA;
122   }
123   else if (sequence->device->state
124            == SATI_DEVICE_STATE_FORMAT_UNIT_IN_PROGRESS)
125   {
126      sati_scsi_sense_data_construct(
127         sequence,
128         scsi_io,
129         SCSI_STATUS_CHECK_CONDITION,
130         SCSI_SENSE_NOT_READY,
131         SCSI_ASC_LUN_FORMAT_IN_PROGRESS,
132         SCSI_ASCQ_LUN_FORMAT_IN_PROGRESS
133      );
134      return SATI_FAILURE_CHECK_RESPONSE_DATA;
135   }
136
137   // The CDB is properly formed and the device is ready.
138   sequence->type = SATI_SEQUENCE_TEST_UNIT_READY;
139
140   sati_ata_check_power_mode_construct(ata_io, sequence);
141   return SATI_SUCCESS;
142}
143
144/**
145 * @brief This method will translate the ATA CHECK POWER MODE register FIS
146 *        response into an appropriate SCSI response.
147 *        For more information on the parameters passed to this method,
148 *        please reference sati_translate_response().
149 *
150 * @return Indicate if the response translation succeeded.
151 * @retval SCI_SUCCESS This is returned if the data translation was
152 *         successful.
153 */
154SATI_STATUS sati_test_unit_ready_translate_response(
155   SATI_TRANSLATOR_SEQUENCE_T * sequence,
156   void                       * scsi_io,
157   void                       * ata_io
158)
159{
160   U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
161
162   /**
163    * SAT dictates:
164    * - If the ATA CHECK POWER MODE command returns an error, then
165    *   return sense data indicating the LOGICAL UNIT DOES NOT RESPONSE
166    *   TO SELECTION.
167    * - All other cases are considered successful.
168    */
169   if (sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT)
170   {
171      sati_scsi_sense_data_construct(
172         sequence,
173         scsi_io,
174         SCSI_STATUS_CHECK_CONDITION,
175         SCSI_SENSE_NOT_READY,
176         SCSI_ASC_LUN_NOT_RESPOND_TO_SELECTION,
177         SCSI_ASCQ_LUN_NOT_RESPOND_TO_SELECTION
178      );
179      return SATI_FAILURE_CHECK_RESPONSE_DATA;
180   }
181
182   return SATI_COMPLETE;
183}
184
185#endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
186
187