isci: Intel(R) C600 Series Chipset Storage Control Unit Driver
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / scsi / isci / core / scic_sds_stp_packet_request.c
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  *   * Neither the name of Intel Corporation nor the names of its
40  *     contributors may be used to endorse or promote products derived
41  *     from this software without specific prior written permission.
42  *
43  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54  */
55 #if !defined(DISABLE_ATAPI)
56
57 #include "intel_ata.h"
58 #include "intel_sas.h"
59 #include "intel_sata.h"
60 #include "intel_sat.h"
61 #include "sati_translator_sequence.h"
62 #include "sci_base_state.h"
63 #include "scic_controller.h"
64 #include "scic_remote_device.h"
65 #include "scic_sds_controller.h"
66 #include "scic_sds_remote_device.h"
67 #include "scic_sds_request.h"
68 #include "scic_sds_stp_packet_request.h"
69 #include "scic_user_callback.h"
70 #include "sci_util.h"
71 #include "scu_completion_codes.h"
72 #include "scu_task_context.h"
73
74
75 /**
76  * This method will fill in the SCU Task Context for a PACKET fis. And
77  *    construct the request STARTED sub-state machine for Packet Protocol IO.
78  * @this_request: This parameter specifies the stp packet request object being
79  *    constructed.
80  *
81  */
82 enum sci_status scic_sds_stp_packet_request_construct(
83         struct scic_sds_request *this_request)
84 {
85         struct sata_fis_reg_h2d *h2d_fis =
86                 scic_stp_io_request_get_h2d_reg_address(
87                         this_request
88                         );
89
90         /*
91          * Work around, we currently only support PACKET DMA protocol, so we
92          * need to make change to Packet Fis features field. */
93         h2d_fis->features = h2d_fis->features | ATA_PACKET_FEATURE_DMA;
94
95         scic_sds_stp_non_ncq_request_construct(this_request);
96
97         /* Build the Packet Fis task context structure */
98         scu_stp_raw_request_construct_task_context(
99                 (struct scic_sds_stp_request *)this_request,
100                 this_request->task_context_buffer
101                 );
102
103         sci_base_state_machine_construct(
104                 &this_request->started_substate_machine,
105                 &this_request->parent.parent,
106                 scic_sds_stp_packet_request_started_substate_table,
107                 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
108                 );
109
110         return SCI_SUCCESS;
111 }
112
113
114 /**
115  * This method will fill in the SCU Task Context for a Packet request command
116  *    phase in PACKET DMA DATA (IN/OUT) type. The following important settings
117  *    are utilized: -# task_type == SCU_TASK_TYPE_PACKET_DMA.  This simply
118  *    indicates that a normal request type (i.e. non-raw frame) is being
119  *    utilized to perform task management. -# control_frame == 1.  This ensures
120  *    that the proper endianess is set so that the bytes are transmitted in the
121  *    right order for a smp request frame.
122  * @this_request: This parameter specifies the smp request object being
123  *    constructed.
124  * @task_context: The task_context to be reconstruct for packet request command
125  *    phase.
126  *
127  */
128 void scu_stp_packet_request_command_phase_construct_task_context(
129         struct scic_sds_request *this_request,
130         struct scu_task_context *task_context)
131 {
132         void *atapi_cdb;
133         u32 atapi_cdb_length;
134         struct scic_sds_stp_request *stp_request = (struct scic_sds_stp_request *)this_request;
135
136         /*
137          * reference: SSTL 1.13.4.2
138          * task_type, sata_direction */
139         if (scic_cb_io_request_get_data_direction(this_request->user_request)
140              == SCI_IO_REQUEST_DATA_OUT) {
141                 task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_OUT;
142                 task_context->sata_direction = 0;
143         } else {  /* todo: for NO_DATA command, we need to send out raw frame. */
144                 task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_IN;
145                 task_context->sata_direction = 1;
146         }
147
148         /* sata header */
149         memset(&(task_context->type.stp), 0, sizeof(struct STP_TASK_CONTEXT));
150         task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
151
152         /*
153          * Copy in the command IU with CDB so that the commandIU address doesn't
154          * change. */
155         memset(this_request->command_buffer, 0, sizeof(struct sata_fis_reg_h2d));
156
157         atapi_cdb =
158                 scic_cb_stp_packet_io_request_get_cdb_address(this_request->user_request);
159
160         atapi_cdb_length =
161                 scic_cb_stp_packet_io_request_get_cdb_length(this_request->user_request);
162
163         memcpy(((u8 *)this_request->command_buffer + sizeof(u32)), atapi_cdb, atapi_cdb_length);
164
165         atapi_cdb_length =
166                 max(atapi_cdb_length, stp_request->type.packet.device_preferred_cdb_length);
167
168         task_context->ssp_command_iu_length =
169                 ((atapi_cdb_length % 4) == 0) ?
170                 (atapi_cdb_length / 4) : ((atapi_cdb_length / 4) + 1);
171
172         /* task phase is set to TX_CMD */
173         task_context->task_phase = 0x1;
174
175         /* retry counter */
176         task_context->stp_retry_count = 0;
177
178         if (scic_cb_request_is_initial_construction(this_request->user_request)) {
179                 /* data transfer size. */
180                 task_context->transfer_length_bytes =
181                         scic_cb_io_request_get_transfer_length(this_request->user_request);
182
183                 /* setup sgl */
184                 scic_sds_request_build_sgl(this_request);
185         } else {
186                 /* data transfer size, need to be 4 bytes aligned. */
187                 task_context->transfer_length_bytes = (SCSI_FIXED_SENSE_DATA_BASE_LENGTH + 2);
188
189                 scic_sds_stp_packet_internal_request_sense_build_sgl(this_request);
190         }
191 }
192
193 /**
194  * This method will fill in the SCU Task Context for a DATA fis containing CDB
195  *    in Raw Frame type. The TC for previous Packet fis was already there, we
196  *    only need to change the H2D fis content.
197  * @this_request: This parameter specifies the smp request object being
198  *    constructed.
199  * @task_context: The task_context to be reconstruct for packet request command
200  *    phase.
201  *
202  */
203 void scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(
204         struct scic_sds_request *this_request,
205         struct scu_task_context *task_context)
206 {
207         void *atapi_cdb =
208                 scic_cb_stp_packet_io_request_get_cdb_address(this_request->user_request);
209
210         u32 atapi_cdb_length =
211                 scic_cb_stp_packet_io_request_get_cdb_length(this_request->user_request);
212
213         memset(this_request->command_buffer, 0, sizeof(struct sata_fis_reg_h2d));
214         memcpy(((u8 *)this_request->command_buffer + sizeof(u32)), atapi_cdb, atapi_cdb_length);
215
216         memset(&(task_context->type.stp), 0, sizeof(struct STP_TASK_CONTEXT));
217         task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
218
219         /*
220          * Note the data send out has to be 4 bytes aligned. Or else out hardware will
221          * patch non-zero bytes and cause the target device unhappy. */
222         task_context->transfer_length_bytes = 12;
223 }
224
225
226 /*
227  * *@brief This methods decode the D2H status FIS and retrieve the sense data,
228  *          then pass the sense data to user request.
229  *
230  ***@param[in] this_request The request receive D2H status FIS.
231  ***@param[in] status_fis The D2H status fis to be processed.
232  *
233  */
234 enum sci_status scic_sds_stp_packet_request_process_status_fis(
235         struct scic_sds_request *this_request,
236         struct sata_fis_reg_d2h *status_fis)
237 {
238         enum sci_status status = SCI_SUCCESS;
239
240         /* TODO: Process the error status fis, retrieve sense data. */
241         if (status_fis->status & ATA_STATUS_REG_ERROR_BIT)
242                 status = SCI_FAILURE_IO_RESPONSE_VALID;
243
244         return status;
245 }
246
247 /*
248  * *@brief This methods builds sgl for internal REQUEST SENSE stp packet
249  *          command using this request response buffer, only one sge is
250  *          needed.
251  *
252  ***@param[in] this_request The request receive request sense data.
253  *
254  */
255 void scic_sds_stp_packet_internal_request_sense_build_sgl(
256         struct scic_sds_request *this_request)
257 {
258         void *sge;
259         struct scu_sgl_element_pair *scu_sgl_list   = NULL;
260         struct scu_task_context *task_context;
261         dma_addr_t physical_address;
262
263         struct sci_ssp_response_iu *rsp_iu =
264                 (struct sci_ssp_response_iu *)this_request->response_buffer;
265
266         sge =  (void *)&rsp_iu->data[0];
267
268         task_context = (struct scu_task_context *)this_request->task_context_buffer;
269         scu_sgl_list = &task_context->sgl_pair_ab;
270
271         scic_cb_io_request_get_physical_address(
272                 scic_sds_request_get_controller(this_request),
273                 this_request,
274                 ((char *)sge),
275                 &physical_address
276                 );
277
278         scu_sgl_list->A.address_upper = sci_cb_physical_address_upper(physical_address);
279         scu_sgl_list->A.address_lower = sci_cb_physical_address_lower(physical_address);
280         scu_sgl_list->A.length = task_context->transfer_length_bytes;
281         scu_sgl_list->A.address_modifier = 0;
282
283         SCU_SGL_ZERO(scu_sgl_list->B);
284 }
285
286 /**
287  * This method processes the completions transport layer (TL) status to
288  *    determine if the Packet FIS was sent successfully. If the Packet FIS was
289  *    sent successfully, then the state for the Packet request transits to
290  *    waiting for a PIO SETUP frame.
291  * @this_request: This parameter specifies the request for which the TC
292  *    completion was received.
293  * @completion_code: This parameter indicates the completion status information
294  *    for the TC.
295  *
296  * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
297  * this method always returns success.
298  */
299 enum sci_status scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler(
300         struct scic_sds_request *this_request,
301         u32 completion_code)
302 {
303         enum sci_status status = SCI_SUCCESS;
304
305         switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
306         case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
307                 scic_sds_request_set_status(
308                         this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
309                         );
310
311                 sci_base_state_machine_change_state(
312                         &this_request->started_substate_machine,
313                         SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
314                         );
315                 break;
316
317         default:
318                 /*
319                  * All other completion status cause the IO to be complete.  If a NAK
320                  * was received, then it is up to the user to retry the request. */
321                 scic_sds_request_set_status(
322                         this_request,
323                         SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
324                         SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
325                         );
326
327                 sci_base_state_machine_change_state(
328                         &this_request->parent.state_machine,
329                         SCI_BASE_REQUEST_STATE_COMPLETED
330                         );
331                 break;
332         }
333
334         return status;
335 }
336
337
338 /**
339  * This method processes an unsolicited frame while the Packet request is
340  *    waiting for a PIO SETUP FIS.  It will release the unsolicited frame, and
341  *    transition the request to the COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
342  *    state.
343  * @this_request: This parameter specifies the request for which the
344  *    unsolicited frame was received.
345  * @frame_index: This parameter indicates the unsolicited frame index that
346  *    should contain the response.
347  *
348  * This method returns an indication of whether the pio setup frame was handled
349  * successfully or not. SCI_SUCCESS Currently this value is always returned and
350  * indicates successful processing of the TC response.
351  */
352 enum sci_status scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler(
353         struct scic_sds_request *request,
354         u32 frame_index)
355 {
356         enum sci_status status;
357         struct sata_fis_header *frame_header;
358         u32 *frame_buffer;
359         struct scic_sds_stp_request *this_request;
360
361         this_request = (struct scic_sds_stp_request *)request;
362
363         status = scic_sds_unsolicited_frame_control_get_header(
364                 &(this_request->parent.owning_controller->uf_control),
365                 frame_index,
366                 (void **)&frame_header
367                 );
368
369         if (status == SCI_SUCCESS) {
370                 BUG_ON(frame_header->fis_type != SATA_FIS_TYPE_PIO_SETUP);
371
372                 /*
373                  * Get from the frame buffer the PIO Setup Data, although we don't need
374                  * any info from this pio setup fis. */
375                 scic_sds_unsolicited_frame_control_get_buffer(
376                         &(this_request->parent.owning_controller->uf_control),
377                         frame_index,
378                         (void **)&frame_buffer
379                         );
380
381                 /*
382                  * Get the data from the PIO Setup
383                  * The SCU Hardware returns first word in the frame_header and the rest
384                  * of the data is in the frame buffer so we need to back up one dword */
385                 this_request->type.packet.device_preferred_cdb_length =
386                         (u16)((struct sata_fis_pio_setup *)(&frame_buffer[-1]))->transfter_count;
387
388                 /* Frame has been decoded return it to the controller */
389                 scic_sds_controller_release_frame(
390                         this_request->parent.owning_controller, frame_index
391                         );
392
393                 sci_base_state_machine_change_state(
394                         &this_request->parent.started_substate_machine,
395                         SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
396                         );
397         } else
398                 dev_err(scic_to_dev(request->owning_controller),
399                         "%s: SCIC IO Request 0x%p could not get frame header "
400                         "for frame index %d, status %x\n",
401                         __func__, this_request, frame_index, status);
402
403         return status;
404 }
405
406
407 /**
408  * This method processes the completions transport layer (TL) status to
409  *    determine if the PACKET command data FIS was sent successfully. If
410  *    successfully, then the state for the packet request transits to COMPLETE
411  *    state. If not successfuly, the request transits to
412  *    COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE.
413  * @this_request: This parameter specifies the request for which the TC
414  *    completion was received.
415  * @completion_code: This parameter indicates the completion status information
416  *    for the TC.
417  *
418  * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
419  * this method always returns success.
420  */
421 enum sci_status scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler(
422         struct scic_sds_request *this_request,
423         u32 completion_code)
424 {
425         enum sci_status status = SCI_SUCCESS;
426         u8 sat_packet_protocol =
427                 scic_cb_request_get_sat_protocol(this_request->user_request);
428
429         switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
430         case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
431                 scic_sds_request_set_status(
432                         this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
433                         );
434
435                 if (sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_IN
436                      || sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_OUT
437                      )
438                         sci_base_state_machine_change_state(
439                                 &this_request->parent.state_machine,
440                                 SCI_BASE_REQUEST_STATE_COMPLETED
441                                 );
442                 else
443                         sci_base_state_machine_change_state(
444                                 &this_request->started_substate_machine,
445                                 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
446                                 );
447                 break;
448
449         case (SCU_TASK_DONE_UNEXP_FIS << SCU_COMPLETION_TL_STATUS_SHIFT):
450                 if (scic_io_request_get_number_of_bytes_transferred(this_request) <
451                     scic_cb_io_request_get_transfer_length(this_request->user_request)) {
452                         scic_sds_request_set_status(
453                                 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY
454                                 );
455
456                         sci_base_state_machine_change_state(
457                                 &this_request->parent.state_machine,
458                                 SCI_BASE_REQUEST_STATE_COMPLETED
459                                 );
460
461                         status = this_request->sci_status;
462                 }
463                 break;
464
465         case (SCU_TASK_DONE_EXCESS_DATA << SCU_COMPLETION_TL_STATUS_SHIFT):
466                 /* In this case, there is no UF coming after. compelte the IO now. */
467                 scic_sds_request_set_status(
468                         this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
469                         );
470
471                 sci_base_state_machine_change_state(
472                         &this_request->parent.state_machine,
473                         SCI_BASE_REQUEST_STATE_COMPLETED
474                         );
475
476                 break;
477
478         default:
479                 if (this_request->sci_status != SCI_SUCCESS) {  /* The io status was set already. This means an UF for the status
480                                                                  * fis was received already.
481                                                                  */
482
483                         /*
484                          * A device suspension event is expected, we need to have the device
485                          * coming out of suspension, then complete the IO. */
486                         sci_base_state_machine_change_state(
487                                 &this_request->started_substate_machine,
488                                 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
489                                 );
490
491                         /* change the device state to ATAPI_ERROR. */
492                         sci_base_state_machine_change_state(
493                                 &this_request->target_device->ready_substate_machine,
494                                 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
495                                 );
496
497                         status = this_request->sci_status;
498                 } else {  /* If receiving any non-sucess TC status, no UF received yet, then an UF for
499                            * the status fis is coming after.
500                            */
501                         scic_sds_request_set_status(
502                                 this_request,
503                                 SCU_TASK_DONE_CHECK_RESPONSE,
504                                 SCI_FAILURE_IO_RESPONSE_VALID
505                                 );
506
507                         sci_base_state_machine_change_state(
508                                 &this_request->started_substate_machine,
509                                 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
510                                 );
511                 }
512                 break;
513         }
514
515         return status;
516 }
517
518
519 /**
520  * This method processes an unsolicited frame.
521  * @this_request: This parameter specifies the request for which the
522  *    unsolicited frame was received.
523  * @frame_index: This parameter indicates the unsolicited frame index that
524  *    should contain the response.
525  *
526  * This method returns an indication of whether the UF frame was handled
527  * successfully or not. SCI_SUCCESS Currently this value is always returned and
528  * indicates successful processing of the TC response.
529  */
530 enum sci_status scic_sds_stp_packet_request_command_phase_common_frame_handler(
531         struct scic_sds_request *request,
532         u32 frame_index)
533 {
534         enum sci_status status;
535         struct sata_fis_header *frame_header;
536         u32 *frame_buffer;
537         struct scic_sds_stp_request *this_request;
538
539         this_request = (struct scic_sds_stp_request *)request;
540
541         status = scic_sds_unsolicited_frame_control_get_header(
542                 &(this_request->parent.owning_controller->uf_control),
543                 frame_index,
544                 (void **)&frame_header
545                 );
546
547         if (status == SCI_SUCCESS) {
548                 BUG_ON(frame_header->fis_type != SATA_FIS_TYPE_REGD2H);
549
550                 /*
551                  * Get from the frame buffer the PIO Setup Data, although we don't need
552                  * any info from this pio setup fis. */
553                 scic_sds_unsolicited_frame_control_get_buffer(
554                         &(this_request->parent.owning_controller->uf_control),
555                         frame_index,
556                         (void **)&frame_buffer
557                         );
558
559                 scic_sds_controller_copy_sata_response(
560                         &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer
561                         );
562
563                 /* Frame has been decoded return it to the controller */
564                 scic_sds_controller_release_frame(
565                         this_request->parent.owning_controller, frame_index
566                         );
567         }
568
569         return status;
570 }
571
572 /**
573  * This method processes an unsolicited frame while the packet request is
574  *    expecting TC completion. It will process the FIS and construct sense data.
575  * @this_request: This parameter specifies the request for which the
576  *    unsolicited frame was received.
577  * @frame_index: This parameter indicates the unsolicited frame index that
578  *    should contain the response.
579  *
580  * This method returns an indication of whether the UF frame was handled
581  * successfully or not. SCI_SUCCESS Currently this value is always returned and
582  * indicates successful processing of the TC response.
583  */
584 enum sci_status scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler(
585         struct scic_sds_request *request,
586         u32 frame_index)
587 {
588         struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
589
590         enum sci_status status =
591                 scic_sds_stp_packet_request_command_phase_common_frame_handler(
592                         request, frame_index);
593
594         if (status == SCI_SUCCESS) {
595                 /* The command has completed with error status from target device. */
596                 status = scic_sds_stp_packet_request_process_status_fis(
597                         request, &this_request->d2h_reg_fis);
598
599                 if (status != SCI_SUCCESS) {
600                         scic_sds_request_set_status(
601                                 &this_request->parent,
602                                 SCU_TASK_DONE_CHECK_RESPONSE,
603                                 status
604                                 );
605                 } else
606                         scic_sds_request_set_status(
607                                 &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS
608                                 );
609         }
610
611         return status;
612 }
613
614
615 /**
616  * This method processes an unsolicited frame while the packet request is
617  *    expecting TC completion. It will process the FIS and construct sense data.
618  * @this_request: This parameter specifies the request for which the
619  *    unsolicited frame was received.
620  * @frame_index: This parameter indicates the unsolicited frame index that
621  *    should contain the response.
622  *
623  * This method returns an indication of whether the UF frame was handled
624  * successfully or not. SCI_SUCCESS Currently this value is always returned and
625  * indicates successful processing of the TC response.
626  */
627 enum sci_status scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler(
628         struct scic_sds_request *request,
629         u32 frame_index)
630 {
631         enum sci_status status =
632                 scic_sds_stp_packet_request_command_phase_common_frame_handler(
633                         request, frame_index);
634
635         struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
636
637         if (status == SCI_SUCCESS) {
638                 /* The command has completed with error status from target device. */
639                 status = scic_sds_stp_packet_request_process_status_fis(
640                         request, &this_request->d2h_reg_fis);
641
642                 if (status != SCI_SUCCESS) {
643                         scic_sds_request_set_status(
644                                 request,
645                                 SCU_TASK_DONE_CHECK_RESPONSE,
646                                 status
647                                 );
648                 } else
649                         scic_sds_request_set_status(
650                                 request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
651                                 );
652
653                 /*
654                  * Always complete the NON_DATA command right away, no need to delay completion
655                  * even an error status fis came from target device. */
656                 sci_base_state_machine_change_state(
657                         &request->parent.state_machine,
658                         SCI_BASE_REQUEST_STATE_COMPLETED
659                         );
660         }
661
662         return status;
663 }
664
665 enum sci_status scic_sds_stp_packet_request_started_completion_delay_complete_handler(
666         struct sci_base_request *request)
667 {
668         struct scic_sds_request *this_request = (struct scic_sds_request *)request;
669
670         sci_base_state_machine_change_state(
671                 &this_request->parent.state_machine,
672                 SCI_BASE_REQUEST_STATE_COMPLETED
673                 );
674
675         return this_request->sci_status;
676 }
677
678 /* --------------------------------------------------------------------------- */
679
680 const struct scic_sds_io_request_state_handler scic_sds_stp_packet_request_started_substate_handler_table[] = {
681         [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
682                 .parent.start_handler    = scic_sds_request_default_start_handler,
683                 .parent.abort_handler    = scic_sds_request_started_state_abort_handler,
684                 .parent.complete_handler = scic_sds_request_default_complete_handler,
685                 .parent.destruct_handler = scic_sds_request_default_destruct_handler
686                 .tc_completion_handler   = scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler,
687                 .event_handler           = scic_sds_request_default_event_handler,
688                 .frame_handler           = scic_sds_request_default_frame_handler
689         },
690         [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE] = {
691                 .parent.start_handler    = scic_sds_request_default_start_handler,
692                 .parent.abort_handler    = scic_sds_request_started_state_abort_handler,
693                 .parent.complete_handler = scic_sds_request_default_complete_handler,
694                 .parent.destruct_handler = scic_sds_request_default_destruct_handler
695                 .tc_completion_handler   = scic_sds_request_default_tc_completion_handler,
696                 .event_handler           = scic_sds_request_default_event_handler,
697                 .frame_handler           = scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler
698         },
699         [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
700                 .parent.start_handler    = scic_sds_request_default_start_handler,
701                 .parent.abort_handler    = scic_sds_request_started_state_abort_handler,
702                 .parent.complete_handler = scic_sds_request_default_complete_handler,
703                 .parent.destruct_handler = scic_sds_request_default_destruct_handler
704                 .tc_completion_handler   = scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler,
705                 .event_handler           = scic_sds_request_default_event_handler,
706                 .frame_handler           = scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler
707         },
708         [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE] = {
709                 .parent.start_handler    = scic_sds_request_default_start_handler,
710                 .parent.abort_handler    = scic_sds_request_started_state_abort_handler,
711                 .parent.complete_handler = scic_sds_request_default_complete_handler,
712                 .parent.destruct_handler = scic_sds_request_default_destruct_handler
713                 .tc_completion_handler   = scic_sds_request_default_tc_completion_handler,
714                 .event_handler           = scic_sds_request_default_event_handler,
715                 .frame_handler           = scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler
716         },
717         [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE] = {
718                 .parent.start_handler    = scic_sds_request_default_start_handler,
719                 .parent.abort_handler    = scic_sds_request_started_state_abort_handler,
720                 .parent.complete_handler = scic_sds_stp_packet_request_started_completion_delay_complete_handler,
721                 .parent.destruct_handler = scic_sds_request_default_destruct_handler
722                 .tc_completion_handler   = scic_sds_request_default_tc_completion_handler,
723                 .event_handler           = scic_sds_request_default_event_handler,
724                 .frame_handler           = scic_sds_request_default_frame_handler
725         },
726 };
727
728 void scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter(
729         struct sci_base_object *object)
730 {
731         struct scic_sds_request *this_request = (struct scic_sds_request *)object;
732
733         SET_STATE_HANDLER(
734                 this_request,
735                 scic_sds_stp_packet_request_started_substate_handler_table,
736                 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
737                 );
738
739         scic_sds_remote_device_set_working_request(
740                 this_request->target_device, this_request
741                 );
742 }
743
744 void scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter(
745         struct sci_base_object *object)
746 {
747         struct scic_sds_request *this_request = (struct scic_sds_request *)object;
748
749         SET_STATE_HANDLER(
750                 this_request,
751                 scic_sds_stp_packet_request_started_substate_handler_table,
752                 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
753                 );
754 }
755
756 void scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter(
757         struct sci_base_object *object)
758 {
759         struct scic_sds_request *this_request = (struct scic_sds_request *)object;
760         u8 sat_packet_protocol =
761                 scic_cb_request_get_sat_protocol(this_request->user_request);
762
763         struct scu_task_context *task_context;
764         enum sci_status status;
765
766         /*
767          * Recycle the TC and reconstruct it for sending out data fis containing
768          * CDB. */
769         task_context = scic_sds_controller_get_task_context_buffer(
770                 this_request->owning_controller, this_request->io_tag);
771
772         if (sat_packet_protocol == SAT_PROTOCOL_PACKET_NON_DATA)
773                 scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(
774                         this_request, task_context);
775         else
776                 scu_stp_packet_request_command_phase_construct_task_context(
777                         this_request, task_context);
778
779         /* send the new TC out. */
780         status = this_request->owning_controller->state_handlers->parent.continue_io_handler(
781                 &this_request->owning_controller->parent,
782                 &this_request->target_device->parent,
783                 &this_request->parent
784                 );
785
786         if (status == SCI_SUCCESS)
787                 SET_STATE_HANDLER(
788                         this_request,
789                         scic_sds_stp_packet_request_started_substate_handler_table,
790                         SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
791                         );
792 }
793
794 void scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter(
795         struct sci_base_object *object)
796 {
797         struct scic_sds_request *this_request = (struct scic_sds_request *)object;
798
799         SET_STATE_HANDLER(
800                 this_request,
801                 scic_sds_stp_packet_request_started_substate_handler_table,
802                 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
803                 );
804 }
805
806 void scic_sds_stp_packet_request_started_completion_delay_enter(
807         struct sci_base_object *object)
808 {
809         struct scic_sds_request *this_request = (struct scic_sds_request *)object;
810
811         SET_STATE_HANDLER(
812                 this_request,
813                 scic_sds_stp_packet_request_started_substate_handler_table,
814                 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
815                 );
816 }
817
818
819 /* --------------------------------------------------------------------------- */
820 const struct sci_base_state scic_sds_stp_packet_request_started_substate_table[] = {
821         [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
822                 .enter_state = scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter,
823         },
824         [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE] = {
825                 .enter_state = scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter,
826         },
827         [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
828                 .enter_state = scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter,
829         },
830         [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE] = {
831                 .enter_state = scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter,
832         },
833         [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE] = {
834                 .enter_state scic_sds_stp_packet_request_started_completion_delay_enter,
835         }
836 };
837
838 #endif /* !defined(DISABLE_ATAPI) */