1230557Sjimharris/*-
2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license.  When using or
3230557Sjimharris * redistributing this file, you may do so under either license.
4230557Sjimharris *
5230557Sjimharris * GPL LICENSE SUMMARY
6230557Sjimharris *
7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8230557Sjimharris *
9230557Sjimharris * This program is free software; you can redistribute it and/or modify
10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as
11230557Sjimharris * published by the Free Software Foundation.
12230557Sjimharris *
13230557Sjimharris * This program is distributed in the hope that it will be useful, but
14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of
15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16230557Sjimharris * General Public License for more details.
17230557Sjimharris *
18230557Sjimharris * You should have received a copy of the GNU General Public License
19230557Sjimharris * along with this program; if not, write to the Free Software
20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21230557Sjimharris * The full GNU General Public License is included in this distribution
22230557Sjimharris * in the file called LICENSE.GPL.
23230557Sjimharris *
24230557Sjimharris * BSD LICENSE
25230557Sjimharris *
26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27230557Sjimharris * All rights reserved.
28230557Sjimharris *
29230557Sjimharris * Redistribution and use in source and binary forms, with or without
30230557Sjimharris * modification, are permitted provided that the following conditions
31230557Sjimharris * are met:
32230557Sjimharris *
33230557Sjimharris *   * Redistributions of source code must retain the above copyright
34230557Sjimharris *     notice, this list of conditions and the following disclaimer.
35230557Sjimharris *   * Redistributions in binary form must reproduce the above copyright
36230557Sjimharris *     notice, this list of conditions and the following disclaimer in
37230557Sjimharris *     the documentation and/or other materials provided with the
38230557Sjimharris *     distribution.
39230557Sjimharris *
40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51230557Sjimharris */
52230557Sjimharris
53230557Sjimharris#include <sys/cdefs.h>
54230557Sjimharris__FBSDID("$FreeBSD$");
55230557Sjimharris
56230557Sjimharris/**
57230557Sjimharris * @file
58230557Sjimharris *
59230557Sjimharris * @brief This file contains the methods and state machines for SATA/STP
60230557Sjimharris *        remote devices.
61230557Sjimharris */
62230557Sjimharris
63230557Sjimharris#include <dev/isci/scil/intel_sat.h>
64230557Sjimharris#include <dev/isci/scil/intel_ata.h>
65230557Sjimharris#include <dev/isci/scil/intel_sata.h>
66230557Sjimharris#include <dev/isci/scil/scic_remote_device.h>
67230557Sjimharris#include <dev/isci/scil/scic_user_callback.h>
68230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h>
69230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h>
70230557Sjimharris#include <dev/isci/scil/scic_sds_port.h>
71230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h>
72230557Sjimharris#include <dev/isci/scil/scic_sds_request.h>
73230557Sjimharris#include <dev/isci/scil/scu_event_codes.h>
74230557Sjimharris#include <dev/isci/scil/scu_completion_codes.h>
75230557Sjimharris#include <dev/isci/scil/sci_base_state.h>
76230557Sjimharris
77230557Sjimharris/**
78230557Sjimharris * This method will perform the STP request completion processing common
79230557Sjimharris * to IO requests and task requests of all types
80230557Sjimharris *
81230557Sjimharris * @param[in] device This parameter specifies the device for which the
82230557Sjimharris *            request is being completed.
83230557Sjimharris * @param[in] request This parameter specifies the request being completed.
84230557Sjimharris *
85230557Sjimharris * @return This method returns an indication as to whether the request
86230557Sjimharris *         processing completed successfully.
87230557Sjimharris */
88230557Sjimharrisstatic
89230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_complete_request(
90230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * device,
91230557Sjimharris   SCI_BASE_REQUEST_T       * request
92230557Sjimharris)
93230557Sjimharris{
94230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
95230557Sjimharris   SCIC_SDS_REQUEST_T       * the_request = (SCIC_SDS_REQUEST_T *)request;
96230557Sjimharris   SCI_STATUS                 status;
97230557Sjimharris
98230557Sjimharris   status = scic_sds_io_request_complete(the_request);
99230557Sjimharris
100230557Sjimharris   if (status == SCI_SUCCESS)
101230557Sjimharris   {
102230557Sjimharris      status = scic_sds_port_complete_io(
103230557Sjimharris                  this_device->owning_port, this_device, the_request
104230557Sjimharris               );
105230557Sjimharris
106230557Sjimharris      if (status == SCI_SUCCESS)
107230557Sjimharris      {
108230557Sjimharris         scic_sds_remote_device_decrement_request_count(this_device);
109230557Sjimharris         if (the_request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED)
110230557Sjimharris         {
111230557Sjimharris            //This request causes hardware error, device needs to be Lun Reset.
112230557Sjimharris            //So here we force the state machine to IDLE state so the rest IOs
113230557Sjimharris            //can reach RNC state handler, these IOs will be completed by RNC with
114230557Sjimharris            //status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE".
115230557Sjimharris            sci_base_state_machine_change_state(
116230557Sjimharris               &this_device->ready_substate_machine,
117230557Sjimharris               SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
118230557Sjimharris            );
119230557Sjimharris         }
120230557Sjimharris         else if (scic_sds_remote_device_get_request_count(this_device) == 0)
121230557Sjimharris         {
122230557Sjimharris            sci_base_state_machine_change_state(
123230557Sjimharris               &this_device->ready_substate_machine,
124230557Sjimharris               SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
125230557Sjimharris            );
126230557Sjimharris         }
127230557Sjimharris      }
128230557Sjimharris   }
129230557Sjimharris
130230557Sjimharris   if (status != SCI_SUCCESS)
131230557Sjimharris   {
132230557Sjimharris      SCIC_LOG_ERROR((
133230557Sjimharris         sci_base_object_get_logger(this_device),
134230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
135230557Sjimharris         "Port:0x%x Device:0x%x Request:0x%x Status:0x%x could not complete\n",
136230557Sjimharris         this_device->owning_port, this_device, the_request, status
137230557Sjimharris      ));
138230557Sjimharris   }
139230557Sjimharris
140230557Sjimharris   return status;
141230557Sjimharris}
142230557Sjimharris
143230557Sjimharris//*****************************************************************************
144230557Sjimharris//*  STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS
145230557Sjimharris//*****************************************************************************
146230557Sjimharris
147230557Sjimharris/**
148230557Sjimharris * This is the READY NCQ substate handler to start task management request. In this
149230557Sjimharris * routine, we suspend and resume the RNC.
150230557Sjimharris *
151230557Sjimharris * @param[in] device The target device a task management request towards to.
152230557Sjimharris * @param[in] request The task request.
153230557Sjimharris *
154230557Sjimharris * @return SCI_STATUS Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status
155230557Sjimharris *     to let controller_start_task_handler know that the controller can't post TC for
156230557Sjimharris *     task request yet, instead, when RNC gets resumed, a controller_continue_task
157230557Sjimharris *     callback will be called.
158230557Sjimharris */
159230557Sjimharrisstatic
160230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_substate_start_request_handler(
161230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * device,
162230557Sjimharris   SCI_BASE_REQUEST_T       * request
163230557Sjimharris)
164230557Sjimharris{
165230557Sjimharris   SCI_STATUS status;
166230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device  = (SCIC_SDS_REMOTE_DEVICE_T *)device;
167230557Sjimharris   SCIC_SDS_REQUEST_T       * this_request = (SCIC_SDS_REQUEST_T       *)request;
168230557Sjimharris
169230557Sjimharris   // Will the port allow the io request to start?
170230557Sjimharris   status = this_device->owning_port->state_handlers->start_io_handler(
171230557Sjimharris      this_device->owning_port,
172230557Sjimharris      this_device,
173230557Sjimharris      this_request
174230557Sjimharris   );
175230557Sjimharris
176230557Sjimharris   if (SCI_SUCCESS == status)
177230557Sjimharris   {
178230557Sjimharris      status =
179230557Sjimharris         scic_sds_remote_node_context_start_task(this_device->rnc, this_request);
180230557Sjimharris
181230557Sjimharris      if (SCI_SUCCESS == status)
182230557Sjimharris      {
183230557Sjimharris         status = this_request->state_handlers->parent.start_handler(request);
184230557Sjimharris      }
185230557Sjimharris
186230557Sjimharris      if (status == SCI_SUCCESS)
187230557Sjimharris      {
188230557Sjimharris         /// @note If the remote device state is not IDLE this will replace
189230557Sjimharris         ///       the request that probably resulted in the task management
190230557Sjimharris         ///       request.
191230557Sjimharris         this_device->working_request = this_request;
192230557Sjimharris
193230557Sjimharris         sci_base_state_machine_change_state(
194230557Sjimharris            &this_device->ready_substate_machine,
195230557Sjimharris            SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
196230557Sjimharris         );
197230557Sjimharris
198230557Sjimharris         //The remote node context must cleanup the TCi to NCQ mapping table.
199230557Sjimharris         //The only way to do this correctly is to either write to the TLCR
200230557Sjimharris         //register or to invalidate and repost the RNC. In either case the
201230557Sjimharris         //remote node context state machine will take the correct action when
202230557Sjimharris         //the remote node context is suspended and later resumed.
203230557Sjimharris         scic_sds_remote_node_context_suspend(
204230557Sjimharris            this_device->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL);
205230557Sjimharris
206230557Sjimharris         scic_sds_remote_node_context_resume(
207230557Sjimharris            this_device->rnc,
208230557Sjimharris            (SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK)
209230557Sjimharris                scic_sds_remote_device_continue_request,
210230557Sjimharris            this_device);
211230557Sjimharris      }
212230557Sjimharris
213230557Sjimharris      scic_sds_remote_device_start_request(this_device,this_request,status);
214230557Sjimharris
215230557Sjimharris      //We need to let the controller start request handler know that it can't
216230557Sjimharris      //post TC yet. We will provide a callback function to post TC when RNC gets
217230557Sjimharris      //resumed.
218230557Sjimharris      return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
219230557Sjimharris   }
220230557Sjimharris
221230557Sjimharris   return status;
222230557Sjimharris}
223230557Sjimharris
224230557Sjimharris//*****************************************************************************
225230557Sjimharris//*  STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
226230557Sjimharris//*****************************************************************************
227230557Sjimharris
228230557Sjimharris/**
229230557Sjimharris * This method will handle the start io operation for a sata device that is in
230230557Sjimharris * the command idle state.
231230557Sjimharris *    - Evalute the type of IO request to be started
232230557Sjimharris *    - If its an NCQ request change to NCQ substate
233230557Sjimharris *    - If its any other command change to the CMD substate
234230557Sjimharris *
235230557Sjimharris * @note If this is a softreset we may want to have a different substate.
236230557Sjimharris *
237230557Sjimharris * @param [in] device
238230557Sjimharris * @param [in] request
239230557Sjimharris *
240230557Sjimharris * @return SCI_STATUS
241230557Sjimharris */
242230557Sjimharrisstatic
243230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_idle_substate_start_io_handler(
244230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * device,
245230557Sjimharris   SCI_BASE_REQUEST_T       * request
246230557Sjimharris)
247230557Sjimharris{
248230557Sjimharris   SCI_STATUS status;
249230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
250230557Sjimharris   SCIC_SDS_REQUEST_T       * io_request  = (SCIC_SDS_REQUEST_T       *)request;
251230557Sjimharris
252230557Sjimharris
253230557Sjimharris   // Will the port allow the io request to start?
254230557Sjimharris   status = this_device->owning_port->state_handlers->start_io_handler(
255230557Sjimharris      this_device->owning_port,
256230557Sjimharris      this_device,
257230557Sjimharris      io_request
258230557Sjimharris   );
259230557Sjimharris
260230557Sjimharris   if (status == SCI_SUCCESS)
261230557Sjimharris   {
262230557Sjimharris      status =
263230557Sjimharris         scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
264230557Sjimharris
265230557Sjimharris      if (status == SCI_SUCCESS)
266230557Sjimharris      {
267230557Sjimharris         status = io_request->state_handlers->parent.start_handler(request);
268230557Sjimharris      }
269230557Sjimharris
270230557Sjimharris      if (status == SCI_SUCCESS)
271230557Sjimharris      {
272230557Sjimharris         if (io_request->sat_protocol == SAT_PROTOCOL_FPDMA)
273230557Sjimharris         {
274230557Sjimharris            sci_base_state_machine_change_state(
275230557Sjimharris               &this_device->ready_substate_machine,
276230557Sjimharris               SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
277230557Sjimharris            );
278230557Sjimharris         }
279230557Sjimharris         else
280230557Sjimharris         {
281230557Sjimharris            this_device->working_request = io_request;
282230557Sjimharris
283230557Sjimharris            sci_base_state_machine_change_state(
284230557Sjimharris               &this_device->ready_substate_machine,
285230557Sjimharris               SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
286230557Sjimharris            );
287230557Sjimharris         }
288230557Sjimharris      }
289230557Sjimharris
290230557Sjimharris      scic_sds_remote_device_start_request(this_device, io_request, status);
291230557Sjimharris   }
292230557Sjimharris
293230557Sjimharris   return status;
294230557Sjimharris}
295230557Sjimharris
296230557Sjimharris
297230557Sjimharris/**
298230557Sjimharris * This method will handle the event for a sata device that is in
299230557Sjimharris * the idle state. We pick up suspension events to handle specifically
300230557Sjimharris * to this state. We resume the RNC right away.
301230557Sjimharris *
302230557Sjimharris * @param [in] device The device received event.
303230557Sjimharris * @param [in] event_code The event code.
304230557Sjimharris *
305230557Sjimharris * @return SCI_STATUS
306230557Sjimharris */
307230557Sjimharrisstatic
308230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_idle_substate_event_handler(
309230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device,
310230557Sjimharris   U32                        event_code
311230557Sjimharris)
312230557Sjimharris{
313230557Sjimharris   SCI_STATUS status;
314230557Sjimharris
315230557Sjimharris   status = scic_sds_remote_device_general_event_handler(this_device, event_code);
316230557Sjimharris
317230557Sjimharris   if (status == SCI_SUCCESS)
318230557Sjimharris   {
319230557Sjimharris      if ((scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
320230557Sjimharris          || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
321230557Sjimharris          && (this_device->rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY))
322230557Sjimharris      {
323230557Sjimharris         status = scic_sds_remote_node_context_resume(
324230557Sjimharris                  this_device->rnc, NULL, NULL);
325230557Sjimharris      }
326230557Sjimharris   }
327230557Sjimharris
328230557Sjimharris   return status;
329230557Sjimharris}
330230557Sjimharris
331230557Sjimharris
332230557Sjimharris//*****************************************************************************
333230557Sjimharris//*  STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
334230557Sjimharris//*****************************************************************************
335230557Sjimharris
336230557Sjimharris/**
337230557Sjimharris *
338230557Sjimharris */
339230557Sjimharrisstatic
340230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
341230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * device,
342230557Sjimharris   SCI_BASE_REQUEST_T       * request
343230557Sjimharris)
344230557Sjimharris{
345230557Sjimharris   SCI_STATUS status;
346230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
347230557Sjimharris   SCIC_SDS_REQUEST_T       * io_request  = (SCIC_SDS_REQUEST_T       *)request;
348230557Sjimharris
349230557Sjimharris   if (io_request->sat_protocol == SAT_PROTOCOL_FPDMA)
350230557Sjimharris   {
351230557Sjimharris      status = this_device->owning_port->state_handlers->start_io_handler(
352230557Sjimharris         this_device->owning_port,
353230557Sjimharris         this_device,
354230557Sjimharris         io_request
355230557Sjimharris      );
356230557Sjimharris
357230557Sjimharris      if (status == SCI_SUCCESS)
358230557Sjimharris      {
359230557Sjimharris         status = scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
360230557Sjimharris
361230557Sjimharris         if (status == SCI_SUCCESS)
362230557Sjimharris         {
363230557Sjimharris            status = io_request->state_handlers->parent.start_handler(request);
364230557Sjimharris         }
365230557Sjimharris
366230557Sjimharris         scic_sds_remote_device_start_request(this_device, io_request, status);
367230557Sjimharris      }
368230557Sjimharris   }
369230557Sjimharris   else
370230557Sjimharris   {
371230557Sjimharris      status = SCI_FAILURE_INVALID_STATE;
372230557Sjimharris   }
373230557Sjimharris
374230557Sjimharris   return status;
375230557Sjimharris}
376230557Sjimharris
377230557Sjimharris/**
378230557Sjimharris *  This method will handle events received while the STP device is in the
379230557Sjimharris *  ready command substate.
380230557Sjimharris *
381230557Sjimharris *  @param [in] this_device This is the device object that is receiving the
382230557Sjimharris *         event.
383230557Sjimharris *  @param [in] event_code The event code to process.
384230557Sjimharris *
385230557Sjimharris *  @return SCI_STATUS
386230557Sjimharris */
387230557Sjimharrisstatic
388230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_event_handler(
389230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device,
390230557Sjimharris   U32                        event_code
391230557Sjimharris)
392230557Sjimharris{
393230557Sjimharris   SCI_STATUS status;
394230557Sjimharris
395230557Sjimharris   status = scic_sds_remote_device_general_event_handler(this_device, event_code);
396230557Sjimharris
397230557Sjimharris   switch (scu_get_event_code(event_code))
398230557Sjimharris   {
399230557Sjimharris   case SCU_EVENT_TL_RNC_SUSPEND_TX:
400230557Sjimharris   case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
401230557Sjimharris      /// @todo We need to decode and understand why the hardware suspended the device.
402230557Sjimharris      ///       The suspension reason was probably due to an SDB error FIS received.
403230557Sjimharris      break;
404230557Sjimharris
405230557Sjimharris   case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DATA_LEN_ERR:
406230557Sjimharris   case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_OFFSET_ERR:
407230557Sjimharris   case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DMASETUP_DIERR:
408230557Sjimharris   case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_XFERCNT_ERR:
409230557Sjimharris   case SCU_EVENT_TL_RNC_SUSPEND_TX_RX_DONE_PLD_LEN_ERR:
410230557Sjimharris      this_device->not_ready_reason =
411230557Sjimharris         SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
412230557Sjimharris
413230557Sjimharris      sci_base_state_machine_change_state(
414230557Sjimharris         &this_device->ready_substate_machine,
415230557Sjimharris         SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
416230557Sjimharris      );
417230557Sjimharris
418230557Sjimharris      // We have a notification that the driver requested a suspend operation
419230557Sjimharris      // this should not happen.
420230557Sjimharris      SCIC_LOG_WARNING((
421230557Sjimharris         sci_base_object_get_logger(this_device),
422230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
423230557Sjimharris         "SCIC Remote device 0x%x received driver suspend event %x while in ncq ready substate %d\n",
424230557Sjimharris         this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
425230557Sjimharris      ));
426230557Sjimharris
427230557Sjimharris      // Since we didnt expect to get here start the device again.
428230557Sjimharris      status = scic_sds_remote_device_resume(this_device);
429230557Sjimharris      break;
430230557Sjimharris
431230557Sjimharris   case SCU_EVENT_POST_RCN_RELEASE:
432230557Sjimharris      /// @todo Do we need to store the suspend state on the device?
433230557Sjimharris      SCIC_LOG_INFO((
434230557Sjimharris         sci_base_object_get_logger(this_device),
435230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
436230557Sjimharris         "SCIC Remote device 0x%x received driver release event %x while in the ready substate %d\n",
437230557Sjimharris         this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
438230557Sjimharris      ));
439230557Sjimharris      break;
440230557Sjimharris
441230557Sjimharris   default:
442230557Sjimharris      // Some other event just log it and continue
443230557Sjimharris      SCIC_LOG_WARNING((
444230557Sjimharris         sci_base_object_get_logger(this_device),
445230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
446230557Sjimharris         "SCIC Remote device 0x%x received driver unexpected event %x while in the ready substate %d\n",
447230557Sjimharris         this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
448230557Sjimharris      ));
449230557Sjimharris
450230557Sjimharris      status = SCI_FAILURE_INVALID_STATE;
451230557Sjimharris      break;
452230557Sjimharris   }
453230557Sjimharris
454230557Sjimharris   return status;
455230557Sjimharris}
456230557Sjimharris
457230557Sjimharris/**
458230557Sjimharris *
459230557Sjimharris *
460230557Sjimharris * @param[in] this_device
461230557Sjimharris * @param[in] frame_index
462230557Sjimharris *
463230557Sjimharris * @return SCI_STATUS
464230557Sjimharris */
465230557Sjimharrisstatic
466230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
467230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device,
468230557Sjimharris   U32                        frame_index
469230557Sjimharris)
470230557Sjimharris{
471230557Sjimharris   SCI_STATUS           status;
472230557Sjimharris   SATA_FIS_HEADER_T  * frame_header;
473230557Sjimharris
474230557Sjimharris   status = scic_sds_unsolicited_frame_control_get_header(
475230557Sjimharris      &(scic_sds_remote_device_get_controller(this_device)->uf_control),
476230557Sjimharris      frame_index,
477230557Sjimharris      (void **)&frame_header
478230557Sjimharris   );
479230557Sjimharris
480230557Sjimharris   if (status == SCI_SUCCESS)
481230557Sjimharris   {
482230557Sjimharris      if (
483230557Sjimharris            (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS)
484230557Sjimharris         && (frame_header->status & ATA_STATUS_REG_ERROR_BIT)
485230557Sjimharris         )
486230557Sjimharris      {
487230557Sjimharris         this_device->not_ready_reason =
488230557Sjimharris            SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
489230557Sjimharris
490230557Sjimharris         /** @todo Check sactive and complete associated IO if any. */
491230557Sjimharris
492230557Sjimharris         sci_base_state_machine_change_state(
493230557Sjimharris            &this_device->ready_substate_machine,
494230557Sjimharris            SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
495230557Sjimharris         );
496230557Sjimharris      }
497230557Sjimharris      else if (
498230557Sjimharris            (frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
499230557Sjimharris         && (frame_header->status & ATA_STATUS_REG_ERROR_BIT)
500230557Sjimharris         )
501230557Sjimharris      {
502230557Sjimharris         // Some devices return D2H FIS when an NCQ error is detected.
503230557Sjimharris         // Treat this like an SDB error FIS ready reason.
504230557Sjimharris         this_device->not_ready_reason =
505230557Sjimharris            SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
506230557Sjimharris
507230557Sjimharris         sci_base_state_machine_change_state(
508230557Sjimharris            &this_device->ready_substate_machine,
509230557Sjimharris            SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
510230557Sjimharris         );
511230557Sjimharris      }
512230557Sjimharris      else
513230557Sjimharris      {
514230557Sjimharris         status = SCI_FAILURE;
515230557Sjimharris      }
516230557Sjimharris
517230557Sjimharris      scic_sds_controller_release_frame(
518230557Sjimharris         scic_sds_remote_device_get_controller(this_device), frame_index
519230557Sjimharris      );
520230557Sjimharris   }
521230557Sjimharris
522230557Sjimharris   return status;
523230557Sjimharris}
524230557Sjimharris
525230557Sjimharris//*****************************************************************************
526230557Sjimharris//*  STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS
527230557Sjimharris//*****************************************************************************
528230557Sjimharris
529230557Sjimharris/**
530230557Sjimharris * This device is already handling a command it can not accept new commands
531230557Sjimharris * until this one is complete.
532230557Sjimharris *
533230557Sjimharris * @param[in] device
534230557Sjimharris * @param[in] request
535230557Sjimharris *
536230557Sjimharris * @return SCI_STATUS
537230557Sjimharris */
538230557Sjimharrisstatic
539230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
540230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * device,
541230557Sjimharris   SCI_BASE_REQUEST_T       * request
542230557Sjimharris)
543230557Sjimharris{
544230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
545230557Sjimharris}
546230557Sjimharris
547230557Sjimharrisstatic
548230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
549230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device,
550230557Sjimharris   U32                        suspend_type
551230557Sjimharris)
552230557Sjimharris{
553230557Sjimharris   SCI_STATUS status;
554230557Sjimharris
555230557Sjimharris   status = scic_sds_remote_node_context_suspend(
556230557Sjimharris      this_device->rnc, suspend_type, NULL, NULL
557230557Sjimharris   );
558230557Sjimharris
559230557Sjimharris   return status;
560230557Sjimharris}
561230557Sjimharris
562230557Sjimharris/**
563230557Sjimharris *
564230557Sjimharris *
565230557Sjimharris * @param[in] this_device
566230557Sjimharris * @param[in] frame_index
567230557Sjimharris *
568230557Sjimharris * @return SCI_STATUS
569230557Sjimharris */
570230557Sjimharrisstatic
571230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
572230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device,
573230557Sjimharris   U32                        frame_index
574230557Sjimharris)
575230557Sjimharris{
576230557Sjimharris   SCI_STATUS status;
577230557Sjimharris
578230557Sjimharris   /// The device doe not process any UF received from the hardware while
579230557Sjimharris   /// in this state.  All unsolicited frames are forwarded to the io request
580230557Sjimharris   /// object.
581230557Sjimharris   status = scic_sds_io_request_frame_handler(
582230557Sjimharris      this_device->working_request,
583230557Sjimharris      frame_index
584230557Sjimharris   );
585230557Sjimharris
586230557Sjimharris   return status;
587230557Sjimharris}
588230557Sjimharris
589230557Sjimharris
590230557Sjimharris//*****************************************************************************
591230557Sjimharris//*  STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
592230557Sjimharris//*****************************************************************************
593230557Sjimharris
594230557Sjimharris
595230557Sjimharris//*****************************************************************************
596230557Sjimharris//*  STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS
597230557Sjimharris//*****************************************************************************
598230557Sjimharrisstatic
599230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
600230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * device,
601230557Sjimharris   SCI_BASE_REQUEST_T       * request
602230557Sjimharris)
603230557Sjimharris{
604230557Sjimharris   return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
605230557Sjimharris}
606230557Sjimharris
607230557Sjimharris
608230557Sjimharris
609230557Sjimharris/**
610230557Sjimharris * This method will perform the STP request (both io or task) completion
611230557Sjimharris * processing for await reset state.
612230557Sjimharris *
613230557Sjimharris * @param[in] device This parameter specifies the device for which the
614230557Sjimharris *            request is being completed.
615230557Sjimharris * @param[in] request This parameter specifies the request being completed.
616230557Sjimharris *
617230557Sjimharris * @return This method returns an indication as to whether the request
618230557Sjimharris *         processing completed successfully.
619230557Sjimharris */
620230557Sjimharrisstatic
621230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
622230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * device,
623230557Sjimharris   SCI_BASE_REQUEST_T       * request
624230557Sjimharris)
625230557Sjimharris{
626230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
627230557Sjimharris   SCIC_SDS_REQUEST_T       * the_request = (SCIC_SDS_REQUEST_T *)request;
628230557Sjimharris   SCI_STATUS                 status;
629230557Sjimharris
630230557Sjimharris   status = scic_sds_io_request_complete(the_request);
631230557Sjimharris
632230557Sjimharris   if (status == SCI_SUCCESS)
633230557Sjimharris   {
634230557Sjimharris      status = scic_sds_port_complete_io(
635230557Sjimharris                  this_device->owning_port, this_device, the_request
636230557Sjimharris               );
637230557Sjimharris
638230557Sjimharris      if (status == SCI_SUCCESS)
639230557Sjimharris         scic_sds_remote_device_decrement_request_count(this_device);
640230557Sjimharris   }
641230557Sjimharris
642230557Sjimharris   if (status != SCI_SUCCESS)
643230557Sjimharris   {
644230557Sjimharris      SCIC_LOG_ERROR((
645230557Sjimharris         sci_base_object_get_logger(this_device),
646230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
647230557Sjimharris         "Port:0x%x Device:0x%x Request:0x%x Status:0x%x could not complete\n",
648230557Sjimharris         this_device->owning_port, this_device, the_request, status
649230557Sjimharris      ));
650230557Sjimharris   }
651230557Sjimharris
652230557Sjimharris   return status;
653230557Sjimharris}
654230557Sjimharris
655230557Sjimharris#if !defined(DISABLE_ATAPI)
656230557Sjimharris//*****************************************************************************
657230557Sjimharris//*  STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE HANDLERS
658230557Sjimharris//*****************************************************************************
659230557Sjimharris
660230557Sjimharris/**
661230557Sjimharris * This method will handle the event for a ATAPI device that is in
662230557Sjimharris * the ATAPI ERROR state. We pick up suspension events to handle specifically
663230557Sjimharris * to this state. We resume the RNC right away. We then complete the outstanding
664230557Sjimharris * IO to this device.
665230557Sjimharris *
666230557Sjimharris * @param [in] device The device received event.
667230557Sjimharris * @param [in] event_code The event code.
668230557Sjimharris *
669230557Sjimharris * @return SCI_STATUS
670230557Sjimharris */
671230557Sjimharrisstatic
672230557SjimharrisSCI_STATUS scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler(
673230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device,
674230557Sjimharris   U32                        event_code
675230557Sjimharris)
676230557Sjimharris{
677230557Sjimharris   SCI_STATUS status;
678230557Sjimharris
679230557Sjimharris   status = scic_sds_remote_device_general_event_handler(this_device, event_code);
680230557Sjimharris
681230557Sjimharris   if (status == SCI_SUCCESS)
682230557Sjimharris   {
683230557Sjimharris      if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
684230557Sjimharris          || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
685230557Sjimharris      {
686230557Sjimharris         status = scic_sds_remote_node_context_resume(
687230557Sjimharris                     this_device->rnc,
688230557Sjimharris                     (SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK)
689230557Sjimharris                        this_device->working_request->state_handlers->parent.complete_handler,
690230557Sjimharris                     (void *)this_device->working_request
691230557Sjimharris                  );
692230557Sjimharris      }
693230557Sjimharris   }
694230557Sjimharris
695230557Sjimharris   return status;
696230557Sjimharris}
697230557Sjimharris#endif // !defined(DISABLE_ATAPI)
698230557Sjimharris
699230557Sjimharris// ---------------------------------------------------------------------------
700230557Sjimharris
701230557SjimharrisSCIC_SDS_REMOTE_DEVICE_STATE_HANDLER_T
702230557Sjimharris   scic_sds_stp_remote_device_ready_substate_handler_table[
703230557Sjimharris                              SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
704230557Sjimharris{
705230557Sjimharris   // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
706230557Sjimharris   {
707230557Sjimharris      {
708230557Sjimharris         scic_sds_remote_device_default_start_handler,
709230557Sjimharris         scic_sds_remote_device_ready_state_stop_handler,
710230557Sjimharris         scic_sds_remote_device_default_fail_handler,
711230557Sjimharris         scic_sds_remote_device_default_destruct_handler,
712230557Sjimharris         scic_sds_remote_device_ready_state_reset_handler,
713230557Sjimharris         scic_sds_remote_device_default_reset_complete_handler,
714230557Sjimharris         scic_sds_stp_remote_device_ready_idle_substate_start_io_handler,
715230557Sjimharris         scic_sds_remote_device_default_complete_request_handler,
716230557Sjimharris         scic_sds_remote_device_default_continue_request_handler,
717230557Sjimharris         scic_sds_stp_remote_device_ready_substate_start_request_handler,
718230557Sjimharris         scic_sds_remote_device_default_complete_request_handler
719230557Sjimharris      },
720230557Sjimharris      scic_sds_remote_device_default_suspend_handler,
721230557Sjimharris      scic_sds_remote_device_default_resume_handler,
722230557Sjimharris      scic_sds_stp_remote_device_ready_idle_substate_event_handler,
723230557Sjimharris      scic_sds_remote_device_default_frame_handler
724230557Sjimharris   },
725230557Sjimharris   // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
726230557Sjimharris   {
727230557Sjimharris      {
728230557Sjimharris         scic_sds_remote_device_default_start_handler,
729230557Sjimharris         scic_sds_remote_device_ready_state_stop_handler,
730230557Sjimharris         scic_sds_remote_device_default_fail_handler,
731230557Sjimharris         scic_sds_remote_device_default_destruct_handler,
732230557Sjimharris         scic_sds_remote_device_ready_state_reset_handler,
733230557Sjimharris         scic_sds_remote_device_default_reset_complete_handler,
734230557Sjimharris         scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler,
735230557Sjimharris         scic_sds_stp_remote_device_complete_request,
736230557Sjimharris         scic_sds_remote_device_default_continue_request_handler,
737230557Sjimharris         scic_sds_stp_remote_device_ready_substate_start_request_handler,
738230557Sjimharris         scic_sds_stp_remote_device_complete_request,
739230557Sjimharris      },
740230557Sjimharris      scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler,
741230557Sjimharris      scic_sds_remote_device_default_resume_handler,
742230557Sjimharris      scic_sds_remote_device_general_event_handler,
743230557Sjimharris      scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
744230557Sjimharris   },
745230557Sjimharris   // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
746230557Sjimharris   {
747230557Sjimharris      {
748230557Sjimharris         scic_sds_remote_device_default_start_handler,
749230557Sjimharris         scic_sds_remote_device_ready_state_stop_handler,
750230557Sjimharris         scic_sds_remote_device_default_fail_handler,
751230557Sjimharris         scic_sds_remote_device_default_destruct_handler,
752230557Sjimharris         scic_sds_remote_device_ready_state_reset_handler,
753230557Sjimharris         scic_sds_remote_device_default_reset_complete_handler,
754230557Sjimharris         scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler,
755230557Sjimharris         scic_sds_stp_remote_device_complete_request,
756230557Sjimharris         scic_sds_remote_device_default_continue_request_handler,
757230557Sjimharris         scic_sds_stp_remote_device_ready_substate_start_request_handler,
758230557Sjimharris         scic_sds_stp_remote_device_complete_request
759230557Sjimharris      },
760230557Sjimharris      scic_sds_remote_device_default_suspend_handler,
761230557Sjimharris      scic_sds_remote_device_default_resume_handler,
762230557Sjimharris      scic_sds_stp_remote_device_ready_ncq_substate_event_handler,
763230557Sjimharris      scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
764230557Sjimharris   },
765230557Sjimharris   // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
766230557Sjimharris   {
767230557Sjimharris      {
768230557Sjimharris         scic_sds_remote_device_default_start_handler,
769230557Sjimharris         scic_sds_remote_device_ready_state_stop_handler,
770230557Sjimharris         scic_sds_remote_device_default_fail_handler,
771230557Sjimharris         scic_sds_remote_device_default_destruct_handler,
772230557Sjimharris         scic_sds_remote_device_ready_state_reset_handler,
773230557Sjimharris         scic_sds_remote_device_default_reset_complete_handler,
774230557Sjimharris         scic_sds_remote_device_default_start_request_handler,
775230557Sjimharris         scic_sds_stp_remote_device_complete_request,
776230557Sjimharris         scic_sds_remote_device_default_continue_request_handler,
777230557Sjimharris         scic_sds_stp_remote_device_ready_substate_start_request_handler,
778230557Sjimharris         scic_sds_stp_remote_device_complete_request
779230557Sjimharris      },
780230557Sjimharris      scic_sds_remote_device_default_suspend_handler,
781230557Sjimharris      scic_sds_remote_device_default_resume_handler,
782230557Sjimharris      scic_sds_remote_device_general_event_handler,
783230557Sjimharris      scic_sds_remote_device_general_frame_handler
784230557Sjimharris   },
785230557Sjimharris#if !defined(DISABLE_ATAPI)
786230557Sjimharris   // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
787230557Sjimharris   {
788230557Sjimharris      {
789230557Sjimharris         scic_sds_remote_device_default_start_handler,
790230557Sjimharris         scic_sds_remote_device_ready_state_stop_handler,
791230557Sjimharris         scic_sds_remote_device_default_fail_handler,
792230557Sjimharris         scic_sds_remote_device_default_destruct_handler,
793230557Sjimharris         scic_sds_remote_device_ready_state_reset_handler,
794230557Sjimharris         scic_sds_remote_device_default_reset_complete_handler,
795230557Sjimharris         scic_sds_remote_device_default_start_request_handler,
796230557Sjimharris         scic_sds_stp_remote_device_complete_request,
797230557Sjimharris         scic_sds_remote_device_default_continue_request_handler,
798230557Sjimharris         scic_sds_stp_remote_device_ready_substate_start_request_handler,
799230557Sjimharris         scic_sds_stp_remote_device_complete_request
800230557Sjimharris      },
801230557Sjimharris      scic_sds_remote_device_default_suspend_handler,
802230557Sjimharris      scic_sds_remote_device_default_resume_handler,
803230557Sjimharris      scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler,
804230557Sjimharris      scic_sds_remote_device_general_frame_handler
805230557Sjimharris   },
806230557Sjimharris#endif
807230557Sjimharris   // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
808230557Sjimharris   {
809230557Sjimharris      {
810230557Sjimharris         scic_sds_remote_device_default_start_handler,
811230557Sjimharris         scic_sds_remote_device_ready_state_stop_handler,
812230557Sjimharris         scic_sds_remote_device_default_fail_handler,
813230557Sjimharris         scic_sds_remote_device_default_destruct_handler,
814230557Sjimharris         scic_sds_remote_device_ready_state_reset_handler,
815230557Sjimharris         scic_sds_remote_device_default_reset_complete_handler,
816230557Sjimharris         scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler,
817230557Sjimharris         scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler,
818230557Sjimharris         scic_sds_remote_device_default_continue_request_handler,
819230557Sjimharris         scic_sds_stp_remote_device_ready_substate_start_request_handler,
820230557Sjimharris         scic_sds_stp_remote_device_complete_request
821230557Sjimharris      },
822230557Sjimharris      scic_sds_remote_device_default_suspend_handler,
823230557Sjimharris      scic_sds_remote_device_default_resume_handler,
824230557Sjimharris      scic_sds_remote_device_general_event_handler,
825230557Sjimharris      scic_sds_remote_device_general_frame_handler
826230557Sjimharris   }
827230557Sjimharris};
828230557Sjimharris
829230557Sjimharris//*****************************************************************************
830230557Sjimharris//*  STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS
831230557Sjimharris//*****************************************************************************
832230557Sjimharris
833230557Sjimharrisstatic
834230557Sjimharrisvoid scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
835230557Sjimharris   void * user_cookie
836230557Sjimharris)
837230557Sjimharris{
838230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device;
839230557Sjimharris   this_device = (SCIC_SDS_REMOTE_DEVICE_T *)user_cookie;
840230557Sjimharris
841230557Sjimharris   // For NCQ operation we do not issue a
842230557Sjimharris   // scic_cb_remote_device_not_ready().  As a result, avoid sending
843230557Sjimharris   // the ready notification.
844230557Sjimharris   if (this_device->ready_substate_machine.previous_state_id
845230557Sjimharris       != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ)
846230557Sjimharris   {
847230557Sjimharris      scic_cb_remote_device_ready(
848230557Sjimharris         scic_sds_remote_device_get_controller(this_device), this_device
849230557Sjimharris      );
850230557Sjimharris   }
851230557Sjimharris}
852230557Sjimharris
853230557Sjimharris//*****************************************************************************
854230557Sjimharris//*  STP REMOTE DEVICE READY IDLE SUBSTATE
855230557Sjimharris//*****************************************************************************
856230557Sjimharris
857230557Sjimharris/**
858230557Sjimharris *
859230557Sjimharris * @param[in] device This is the SCI base object which is cast into a
860230557Sjimharris *       SCIC_SDS_REMOTE_DEVICE object.
861230557Sjimharris *
862230557Sjimharris * @return none
863230557Sjimharris */
864230557Sjimharrisstatic
865230557Sjimharrisvoid scic_sds_stp_remote_device_ready_idle_substate_enter(
866230557Sjimharris   SCI_BASE_OBJECT_T * device
867230557Sjimharris)
868230557Sjimharris{
869230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device;
870230557Sjimharris
871230557Sjimharris   this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
872230557Sjimharris
873230557Sjimharris   SET_STATE_HANDLER(
874230557Sjimharris      this_device,
875230557Sjimharris      scic_sds_stp_remote_device_ready_substate_handler_table,
876230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
877230557Sjimharris   );
878230557Sjimharris
879230557Sjimharris   this_device->working_request = NULL;
880230557Sjimharris
881230557Sjimharris   if (scic_sds_remote_node_context_is_ready(this_device->rnc))
882230557Sjimharris   {
883230557Sjimharris      // Since the RNC is ready, it's alright to finish completion
884230557Sjimharris      // processing (e.g. signal the remote device is ready).
885230557Sjimharris      scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
886230557Sjimharris         this_device
887230557Sjimharris      );
888230557Sjimharris   }
889230557Sjimharris   else
890230557Sjimharris   {
891230557Sjimharris      scic_sds_remote_node_context_resume(
892230557Sjimharris         this_device->rnc,
893230557Sjimharris         scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler,
894230557Sjimharris         this_device
895230557Sjimharris      );
896230557Sjimharris   }
897230557Sjimharris}
898230557Sjimharris
899230557Sjimharris//*****************************************************************************
900230557Sjimharris//*  STP REMOTE DEVICE READY CMD SUBSTATE
901230557Sjimharris//*****************************************************************************
902230557Sjimharris
903230557Sjimharris/**
904230557Sjimharris *
905230557Sjimharris *
906230557Sjimharris * @param[in] device This is the SCI base object which is cast into a
907230557Sjimharris *       SCIC_SDS_REMOTE_DEVICE object.
908230557Sjimharris *
909230557Sjimharris * @return none
910230557Sjimharris */
911230557Sjimharrisstatic
912230557Sjimharrisvoid scic_sds_stp_remote_device_ready_cmd_substate_enter(
913230557Sjimharris   SCI_BASE_OBJECT_T * device
914230557Sjimharris)
915230557Sjimharris{
916230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device;
917230557Sjimharris
918230557Sjimharris   this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
919230557Sjimharris
920230557Sjimharris   ASSERT(this_device->working_request != NULL);
921230557Sjimharris
922230557Sjimharris   SET_STATE_HANDLER(
923230557Sjimharris      this_device,
924230557Sjimharris      scic_sds_stp_remote_device_ready_substate_handler_table,
925230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
926230557Sjimharris   );
927230557Sjimharris
928230557Sjimharris   scic_cb_remote_device_not_ready(
929230557Sjimharris      scic_sds_remote_device_get_controller(this_device),
930230557Sjimharris      this_device,
931230557Sjimharris      SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED
932230557Sjimharris   );
933230557Sjimharris}
934230557Sjimharris
935230557Sjimharris//*****************************************************************************
936230557Sjimharris//*  STP REMOTE DEVICE READY NCQ SUBSTATE
937230557Sjimharris//*****************************************************************************
938230557Sjimharris
939230557Sjimharris/**
940230557Sjimharris *
941230557Sjimharris *
942230557Sjimharris * @param[in] device This is the SCI base object which is cast into a
943230557Sjimharris *       SCIC_SDS_REMOTE_DEVICE object.
944230557Sjimharris *
945230557Sjimharris * @return none
946230557Sjimharris */
947230557Sjimharrisstatic
948230557Sjimharrisvoid scic_sds_stp_remote_device_ready_ncq_substate_enter(
949230557Sjimharris   SCI_BASE_OBJECT_T * device
950230557Sjimharris)
951230557Sjimharris{
952230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device;
953230557Sjimharris
954230557Sjimharris   this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
955230557Sjimharris
956230557Sjimharris   SET_STATE_HANDLER(
957230557Sjimharris      this_device,
958230557Sjimharris      scic_sds_stp_remote_device_ready_substate_handler_table,
959230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
960230557Sjimharris   );
961230557Sjimharris}
962230557Sjimharris
963230557Sjimharris//*****************************************************************************
964230557Sjimharris//*  STP REMOTE DEVICE READY NCQ ERROR SUBSTATE
965230557Sjimharris//*****************************************************************************
966230557Sjimharris
967230557Sjimharris/**
968230557Sjimharris *
969230557Sjimharris *
970230557Sjimharris * @param[in] device This is the SCI base object which is cast into a
971230557Sjimharris *       SCIC_SDS_REMOTE_DEVICE object.
972230557Sjimharris *
973230557Sjimharris * @return none
974230557Sjimharris */
975230557Sjimharrisstatic
976230557Sjimharrisvoid scic_sds_stp_remote_device_ready_ncq_error_substate_enter(
977230557Sjimharris   SCI_BASE_OBJECT_T * device
978230557Sjimharris)
979230557Sjimharris{
980230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device;
981230557Sjimharris
982230557Sjimharris   this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
983230557Sjimharris
984230557Sjimharris   SET_STATE_HANDLER(
985230557Sjimharris      this_device,
986230557Sjimharris      scic_sds_stp_remote_device_ready_substate_handler_table,
987230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
988230557Sjimharris   );
989230557Sjimharris
990230557Sjimharris   if(this_device->not_ready_reason ==
991230557Sjimharris         SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
992230557Sjimharris   {
993230557Sjimharris      scic_cb_remote_device_not_ready(
994230557Sjimharris         scic_sds_remote_device_get_controller(this_device),
995230557Sjimharris         this_device,
996230557Sjimharris         this_device->not_ready_reason
997230557Sjimharris      );
998230557Sjimharris   }
999230557Sjimharris}
1000230557Sjimharris
1001230557Sjimharris//*****************************************************************************
1002230557Sjimharris//*  STP REMOTE DEVICE READY AWAIT RESET SUBSTATE
1003230557Sjimharris//*****************************************************************************
1004230557Sjimharris
1005230557Sjimharris/**
1006230557Sjimharris * @brief The enter routine to READY AWAIT RESET substate.
1007230557Sjimharris *
1008230557Sjimharris * @param[in] device This is the SCI base object which is cast into a
1009230557Sjimharris *       SCIC_SDS_REMOTE_DEVICE object.
1010230557Sjimharris *
1011230557Sjimharris * @return none
1012230557Sjimharris */
1013230557Sjimharrisstatic
1014230557Sjimharrisvoid scic_sds_stp_remote_device_ready_await_reset_substate_enter(
1015230557Sjimharris   SCI_BASE_OBJECT_T * device
1016230557Sjimharris)
1017230557Sjimharris{
1018230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device;
1019230557Sjimharris
1020230557Sjimharris   this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
1021230557Sjimharris
1022230557Sjimharris   SET_STATE_HANDLER(
1023230557Sjimharris      this_device,
1024230557Sjimharris      scic_sds_stp_remote_device_ready_substate_handler_table,
1025230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
1026230557Sjimharris   );
1027230557Sjimharris}
1028230557Sjimharris
1029230557Sjimharris#if !defined(DISABLE_ATAPI)
1030230557Sjimharris//*****************************************************************************
1031230557Sjimharris//*  STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE
1032230557Sjimharris//*****************************************************************************
1033230557Sjimharris
1034230557Sjimharris/**
1035230557Sjimharris * @brief The enter routine to READY ATAPI ERROR substate.
1036230557Sjimharris *
1037230557Sjimharris * @param[in] device This is the SCI base object which is cast into a
1038230557Sjimharris *       SCIC_SDS_REMOTE_DEVICE object.
1039230557Sjimharris *
1040230557Sjimharris * @return none
1041230557Sjimharris */
1042230557Sjimharrisstatic
1043230557Sjimharrisvoid scic_sds_stp_remote_device_ready_atapi_error_substate_enter(
1044230557Sjimharris   SCI_BASE_OBJECT_T * device
1045230557Sjimharris)
1046230557Sjimharris{
1047230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device;
1048230557Sjimharris
1049230557Sjimharris   this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
1050230557Sjimharris
1051230557Sjimharris   SET_STATE_HANDLER(
1052230557Sjimharris      this_device,
1053230557Sjimharris      scic_sds_stp_remote_device_ready_substate_handler_table,
1054230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
1055230557Sjimharris   );
1056230557Sjimharris}
1057230557Sjimharris#endif // !defined(DISABLE_ATAPI)
1058230557Sjimharris
1059230557Sjimharris// ---------------------------------------------------------------------------
1060230557Sjimharris
1061230557SjimharrisSCI_BASE_STATE_T
1062230557Sjimharris   scic_sds_stp_remote_device_ready_substate_table[
1063230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
1064230557Sjimharris{
1065230557Sjimharris   {
1066230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE,
1067230557Sjimharris      scic_sds_stp_remote_device_ready_idle_substate_enter,
1068230557Sjimharris      NULL
1069230557Sjimharris   },
1070230557Sjimharris   {
1071230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD,
1072230557Sjimharris      scic_sds_stp_remote_device_ready_cmd_substate_enter,
1073230557Sjimharris      NULL
1074230557Sjimharris   },
1075230557Sjimharris   {
1076230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ,
1077230557Sjimharris      scic_sds_stp_remote_device_ready_ncq_substate_enter,
1078230557Sjimharris      NULL
1079230557Sjimharris   },
1080230557Sjimharris   {
1081230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR,
1082230557Sjimharris      scic_sds_stp_remote_device_ready_ncq_error_substate_enter,
1083230557Sjimharris      NULL
1084230557Sjimharris   },
1085230557Sjimharris#if !defined(DISABLE_ATAPI)
1086230557Sjimharris   {
1087230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR,
1088230557Sjimharris      scic_sds_stp_remote_device_ready_atapi_error_substate_enter,
1089230557Sjimharris      NULL
1090230557Sjimharris   },
1091230557Sjimharris#endif
1092230557Sjimharris   {
1093230557Sjimharris      SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET,
1094230557Sjimharris      scic_sds_stp_remote_device_ready_await_reset_substate_enter,
1095230557Sjimharris      NULL
1096230557Sjimharris   }
1097230557Sjimharris};
1098230557Sjimharris
1099