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 This file contains the SMP remote device
60230557Sjimharris *        object methods and it's state machines.
61230557Sjimharris */
62230557Sjimharris
63230557Sjimharris#include <dev/isci/scil/scic_user_callback.h>
64230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h>
65230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h>
66230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h>
67230557Sjimharris#include <dev/isci/scil/scic_sds_port.h>
68230557Sjimharris#include <dev/isci/scil/scic_sds_request.h>
69230557Sjimharris#include <dev/isci/scil/scu_event_codes.h>
70230557Sjimharris#include <dev/isci/scil/scu_task_context.h>
71230557Sjimharris#include <dev/isci/scil/scic_remote_device.h>
72230557Sjimharris
73230557Sjimharris//*****************************************************************************
74230557Sjimharris//*  SMP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
75230557Sjimharris//*****************************************************************************
76230557Sjimharris
77230557Sjimharris/**
78230557Sjimharris * This method will handle the start io operation for a SMP device that is in
79230557Sjimharris * the idle state.
80230557Sjimharris *
81230557Sjimharris * @param [in] device The device the io is sent to.
82230557Sjimharris * @param [in] request The io to start.
83230557Sjimharris *
84230557Sjimharris * @return SCI_STATUS
85230557Sjimharris */
86230557Sjimharrisstatic
87230557SjimharrisSCI_STATUS scic_sds_smp_remote_device_ready_idle_substate_start_io_handler(
88230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * device,
89230557Sjimharris   SCI_BASE_REQUEST_T       * request
90230557Sjimharris)
91230557Sjimharris{
92230557Sjimharris   SCI_STATUS status;
93230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
94230557Sjimharris   SCIC_SDS_REQUEST_T       * io_request  = (SCIC_SDS_REQUEST_T       *)request;
95230557Sjimharris
96230557Sjimharris   // Will the port allow the io request to start?
97230557Sjimharris   status = this_device->owning_port->state_handlers->start_io_handler(
98230557Sjimharris      this_device->owning_port,
99230557Sjimharris      this_device,
100230557Sjimharris      io_request
101230557Sjimharris   );
102230557Sjimharris
103230557Sjimharris   if (status == SCI_SUCCESS)
104230557Sjimharris   {
105230557Sjimharris      status =
106230557Sjimharris         scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
107230557Sjimharris
108230557Sjimharris      if (status == SCI_SUCCESS)
109230557Sjimharris      {
110230557Sjimharris         status = scic_sds_request_start(io_request);
111230557Sjimharris      }
112230557Sjimharris
113230557Sjimharris      if (status == SCI_SUCCESS)
114230557Sjimharris      {
115230557Sjimharris         this_device->working_request = io_request;
116230557Sjimharris
117230557Sjimharris         sci_base_state_machine_change_state(
118230557Sjimharris               &this_device->ready_substate_machine,
119230557Sjimharris               SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD
120230557Sjimharris         );
121230557Sjimharris      }
122230557Sjimharris
123230557Sjimharris      scic_sds_remote_device_start_request(this_device, io_request, status);
124230557Sjimharris   }
125230557Sjimharris
126230557Sjimharris   return status;
127230557Sjimharris}
128230557Sjimharris
129230557Sjimharris
130230557Sjimharris//******************************************************************************
131230557Sjimharris//* SMP REMOTE DEVICE READY SUBSTATE CMD HANDLERS
132230557Sjimharris//******************************************************************************
133230557Sjimharris/**
134230557Sjimharris * This device is already handling a command it can not accept new commands
135230557Sjimharris * until this one is complete.
136230557Sjimharris *
137230557Sjimharris * @param[in] device This is the device object that is receiving the IO.
138230557Sjimharris *
139230557Sjimharris * @param[in] request The io to start.
140230557Sjimharris *
141230557Sjimharris * @return SCI_STATUS
142230557Sjimharris */
143230557Sjimharrisstatic
144230557SjimharrisSCI_STATUS scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler(
145230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * device,
146230557Sjimharris   SCI_BASE_REQUEST_T       * request
147230557Sjimharris)
148230557Sjimharris{
149230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
150230557Sjimharris}
151230557Sjimharris
152230557Sjimharris
153230557Sjimharris/**
154230557Sjimharris * @brief this is the complete_io_handler for smp device at ready cmd substate.
155230557Sjimharris *
156230557Sjimharris * @param[in] device This is the device object that is receiving the IO.
157230557Sjimharris * @param[in] request The io to start.
158230557Sjimharris *
159230557Sjimharris * @return SCI_STATUS
160230557Sjimharris */
161230557Sjimharrisstatic
162230557SjimharrisSCI_STATUS scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler(
163230557Sjimharris   SCI_BASE_REMOTE_DEVICE_T * device,
164230557Sjimharris   SCI_BASE_REQUEST_T       * request
165230557Sjimharris)
166230557Sjimharris{
167230557Sjimharris   SCI_STATUS                 status;
168230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device;
169230557Sjimharris   SCIC_SDS_REQUEST_T       * the_request;
170230557Sjimharris
171230557Sjimharris   this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
172230557Sjimharris   the_request = (SCIC_SDS_REQUEST_T       *)request;
173230557Sjimharris
174230557Sjimharris   status = scic_sds_io_request_complete(the_request);
175230557Sjimharris
176230557Sjimharris   if (status == SCI_SUCCESS)
177230557Sjimharris   {
178230557Sjimharris      status = scic_sds_port_complete_io(
179230557Sjimharris         this_device->owning_port, this_device, the_request);
180230557Sjimharris
181230557Sjimharris      if (status == SCI_SUCCESS)
182230557Sjimharris      {
183230557Sjimharris       scic_sds_remote_device_decrement_request_count(this_device);
184230557Sjimharris         sci_base_state_machine_change_state(
185230557Sjimharris            &this_device->ready_substate_machine,
186230557Sjimharris            SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
187230557Sjimharris         );
188230557Sjimharris      }
189230557Sjimharris      else
190230557Sjimharris      {
191230557Sjimharris         SCIC_LOG_ERROR((
192230557Sjimharris            sci_base_object_get_logger(this_device),
193230557Sjimharris            SCIC_LOG_OBJECT_SMP_REMOTE_TARGET,
194230557Sjimharris            "SCIC SDS Remote Device 0x%x io request 0x%x could not be completd on the port 0x%x failed with status %d.\n",
195230557Sjimharris            this_device, the_request, this_device->owning_port, status
196230557Sjimharris         ));
197230557Sjimharris      }
198230557Sjimharris   }
199230557Sjimharris
200230557Sjimharris   return status;
201230557Sjimharris}
202230557Sjimharris
203230557Sjimharris/**
204230557Sjimharris * @brief This is frame handler for smp device ready cmd substate.
205230557Sjimharris *
206230557Sjimharris * @param[in] this_device This is the device object that is receiving the frame.
207230557Sjimharris * @param[in] frame_index The index for the frame received.
208230557Sjimharris *
209230557Sjimharris * @return SCI_STATUS
210230557Sjimharris */
211230557Sjimharrisstatic
212230557SjimharrisSCI_STATUS scic_sds_smp_remote_device_ready_cmd_substate_frame_handler(
213230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device,
214230557Sjimharris   U32                        frame_index
215230557Sjimharris)
216230557Sjimharris{
217230557Sjimharris   SCI_STATUS status;
218230557Sjimharris
219230557Sjimharris   /// The device does not process any UF received from the hardware while
220230557Sjimharris   /// in this state.  All unsolicited frames are forwarded to the io request
221230557Sjimharris   /// object.
222230557Sjimharris   status = scic_sds_io_request_frame_handler(
223230557Sjimharris      this_device->working_request,
224230557Sjimharris      frame_index
225230557Sjimharris   );
226230557Sjimharris
227230557Sjimharris   return status;
228230557Sjimharris}
229230557Sjimharris
230230557Sjimharris// ---------------------------------------------------------------------------
231230557Sjimharris
232230557SjimharrisSCIC_SDS_REMOTE_DEVICE_STATE_HANDLER_T
233230557Sjimharris   scic_sds_smp_remote_device_ready_substate_handler_table[
234230557Sjimharris                              SCIC_SDS_SMP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
235230557Sjimharris{
236230557Sjimharris   // SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
237230557Sjimharris   {
238230557Sjimharris      {
239230557Sjimharris         scic_sds_remote_device_default_start_handler,
240230557Sjimharris         scic_sds_remote_device_ready_state_stop_handler,
241230557Sjimharris         scic_sds_remote_device_default_fail_handler,
242230557Sjimharris         scic_sds_remote_device_default_destruct_handler,
243230557Sjimharris         scic_sds_remote_device_default_reset_handler,
244230557Sjimharris         scic_sds_remote_device_default_reset_complete_handler,
245230557Sjimharris         scic_sds_smp_remote_device_ready_idle_substate_start_io_handler,
246230557Sjimharris         scic_sds_remote_device_default_complete_request_handler,
247230557Sjimharris         scic_sds_remote_device_default_continue_request_handler,
248230557Sjimharris         scic_sds_remote_device_default_start_request_handler,
249230557Sjimharris         scic_sds_remote_device_default_complete_request_handler
250230557Sjimharris      },
251230557Sjimharris      scic_sds_remote_device_default_suspend_handler,
252230557Sjimharris      scic_sds_remote_device_default_resume_handler,
253230557Sjimharris      scic_sds_remote_device_general_event_handler,
254230557Sjimharris      scic_sds_remote_device_default_frame_handler
255230557Sjimharris   },
256230557Sjimharris   // SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD
257230557Sjimharris   {
258230557Sjimharris      {
259230557Sjimharris         scic_sds_remote_device_default_start_handler,
260230557Sjimharris         scic_sds_remote_device_ready_state_stop_handler,
261230557Sjimharris         scic_sds_remote_device_default_fail_handler,
262230557Sjimharris         scic_sds_remote_device_default_destruct_handler,
263230557Sjimharris         scic_sds_remote_device_default_reset_handler,
264230557Sjimharris         scic_sds_remote_device_default_reset_complete_handler,
265230557Sjimharris         scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler,
266230557Sjimharris         scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler,
267230557Sjimharris         scic_sds_remote_device_default_continue_request_handler,
268230557Sjimharris         scic_sds_remote_device_default_start_request_handler,
269230557Sjimharris         scic_sds_remote_device_default_complete_request_handler
270230557Sjimharris      },
271230557Sjimharris      scic_sds_remote_device_default_suspend_handler,
272230557Sjimharris      scic_sds_remote_device_default_resume_handler,
273230557Sjimharris      scic_sds_remote_device_general_event_handler,
274230557Sjimharris      scic_sds_smp_remote_device_ready_cmd_substate_frame_handler
275230557Sjimharris   }
276230557Sjimharris};
277230557Sjimharris
278230557Sjimharris/**
279230557Sjimharris * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE enter method. This
280230557Sjimharris * method sets the ready cmd substate handlers and reports the device as ready.
281230557Sjimharris *
282230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast into a
283230557Sjimharris *       SCIC_SDS_REMOTE_DEVICE.
284230557Sjimharris *
285230557Sjimharris * @return none
286230557Sjimharris */
287230557Sjimharrisstatic
288230557Sjimharrisvoid scic_sds_smp_remote_device_ready_idle_substate_enter(
289230557Sjimharris   SCI_BASE_OBJECT_T *object
290230557Sjimharris)
291230557Sjimharris{
292230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object;
293230557Sjimharris
294230557Sjimharris   SET_STATE_HANDLER(
295230557Sjimharris      this_device,
296230557Sjimharris      scic_sds_smp_remote_device_ready_substate_handler_table,
297230557Sjimharris      SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
298230557Sjimharris   );
299230557Sjimharris
300230557Sjimharris   scic_cb_remote_device_ready(
301230557Sjimharris      scic_sds_remote_device_get_controller(this_device), this_device);
302230557Sjimharris}
303230557Sjimharris
304230557Sjimharris/**
305230557Sjimharris * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD enter method. This
306230557Sjimharris * method sets the remote device objects ready cmd substate handlers, and notify
307230557Sjimharris * core user that the device is not ready.
308230557Sjimharris *
309230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast into a
310230557Sjimharris *       SCIC_SDS_REMOTE_DEVICE.
311230557Sjimharris *
312230557Sjimharris * @return none
313230557Sjimharris */
314230557Sjimharrisstatic
315230557Sjimharrisvoid scic_sds_smp_remote_device_ready_cmd_substate_enter(
316230557Sjimharris   SCI_BASE_OBJECT_T *object
317230557Sjimharris)
318230557Sjimharris{
319230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object;
320230557Sjimharris
321230557Sjimharris   ASSERT(this_device->working_request != NULL);
322230557Sjimharris
323230557Sjimharris   SET_STATE_HANDLER(
324230557Sjimharris      this_device,
325230557Sjimharris      scic_sds_smp_remote_device_ready_substate_handler_table,
326230557Sjimharris      SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD
327230557Sjimharris   );
328230557Sjimharris
329230557Sjimharris   scic_cb_remote_device_not_ready(
330230557Sjimharris      scic_sds_remote_device_get_controller(this_device),
331230557Sjimharris      this_device,
332230557Sjimharris      SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED
333230557Sjimharris   );
334230557Sjimharris}
335230557Sjimharris
336230557Sjimharris/**
337230557Sjimharris * This is the SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_CMD exit method.
338230557Sjimharris *
339230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast into a
340230557Sjimharris *       SCIC_SDS_REMOTE_DEVICE.
341230557Sjimharris *
342230557Sjimharris * @return none
343230557Sjimharris */
344230557Sjimharrisstatic
345230557Sjimharrisvoid scic_sds_smp_remote_device_ready_cmd_substate_exit(
346230557Sjimharris   SCI_BASE_OBJECT_T *object
347230557Sjimharris)
348230557Sjimharris{
349230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object;
350230557Sjimharris
351230557Sjimharris   this_device->working_request = NULL;
352230557Sjimharris}
353230557Sjimharris
354230557Sjimharris// ---------------------------------------------------------------------------
355230557Sjimharris
356230557SjimharrisSCI_BASE_STATE_T
357230557Sjimharris   scic_sds_smp_remote_device_ready_substate_table[
358230557Sjimharris                     SCIC_SDS_SMP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
359230557Sjimharris{
360230557Sjimharris   {
361230557Sjimharris      SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE,
362230557Sjimharris      scic_sds_smp_remote_device_ready_idle_substate_enter,
363230557Sjimharris      NULL
364230557Sjimharris   },
365230557Sjimharris   {
366230557Sjimharris      SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD,
367230557Sjimharris      scic_sds_smp_remote_device_ready_cmd_substate_enter,
368230557Sjimharris      scic_sds_smp_remote_device_ready_cmd_substate_exit
369230557Sjimharris   }
370230557Sjimharris};
371230557Sjimharris
372