1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3 *
4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license.
6 *
7 * GPL LICENSE SUMMARY
8 *
9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23 * The full GNU General Public License is included in this distribution
24 * in the file called LICENSE.GPL.
25 *
26 * BSD LICENSE
27 *
28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29 * All rights reserved.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 *
35 * * Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * * Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in
39 * the documentation and/or other materials provided with the
40 * distribution.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 */
54
55 #include <sys/cdefs.h>
56 __FBSDID("$FreeBSD$");
57
58 #include <dev/isci/scil/intel_sat.h>
59 #include <dev/isci/scil/intel_sata.h>
60 #include <dev/isci/scil/sci_types.h>
61 #include <dev/isci/scil/scic_remote_device.h>
62 #include <dev/isci/scil/scic_user_callback.h>
63 #include <dev/isci/scil/scic_sds_controller.h>
64 #include <dev/isci/scil/scic_sds_remote_device.h>
65 #include <dev/isci/scil/scic_sds_stp_request.h>
66 #include <dev/isci/scil/scic_sds_stp_pio_request.h>
67 #include <dev/isci/scil/scic_sds_logger.h>
68 #include <dev/isci/sci_environment.h>
69 #include <dev/isci/scil/sci_base_state_machine.h>
70 #include <dev/isci/scil/scu_task_context.h>
71 #include <dev/isci/scil/intel_ata.h>
72 #include <dev/isci/scil/sci_util.h>
73 #include <dev/isci/scil/scic_sds_logger.h>
74 #include <dev/isci/scil/scic_sds_request.h>
75 #include <dev/isci/scil/scic_sds_stp_request.h>
76 #include <dev/isci/scil/scu_completion_codes.h>
77 #include <dev/isci/scil/scu_event_codes.h>
78 #include <dev/isci/scil/sci_base_state.h>
79 #include <dev/isci/scil/scic_sds_unsolicited_frame_control.h>
80 #include <dev/isci/scil/scic_io_request.h>
81
82 #if !defined(DISABLE_ATAPI)
83 #include <dev/isci/scil/scic_sds_stp_packet_request.h>
84 #endif
85
86 /**
87 * This macro returns the address of the stp h2d reg fis buffer in the io
88 * request memory
89 */
90 #define scic_sds_stp_request_get_h2d_reg_buffer_unaligned(memory) \
91 ((SATA_FIS_REG_H2D_T *)( \
92 ((char *)(memory)) + sizeof(SCIC_SDS_STP_REQUEST_T) \
93 ))
94
95 /**
96 * This macro aligns the stp command buffer in DWORD alignment
97 */
98 #define scic_sds_stp_request_align_h2d_reg_buffer(address) \
99 ((SATA_FIS_REG_H2D_T *)( \
100 (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \
101 & ~(sizeof(U32)- 1) \
102 ))
103
104 /**
105 * This macro returns the DWORD-aligned stp command buffer
106 */
107 #define scic_sds_stp_request_get_h2d_reg_buffer(memory) \
108 ((SATA_FIS_REG_H2D_T *) \
109 ((char *)scic_sds_stp_request_align_h2d_reg_buffer( \
110 (char *) scic_sds_stp_request_get_h2d_reg_buffer_unaligned(memory) \
111 )))
112
113 /**
114 * This macro returns the address of the stp response buffer in the io
115 * request memory
116 */
117 #define scic_sds_stp_request_get_response_buffer_unaligned(memory) \
118 ((SATA_FIS_REG_D2H_T *)( \
119 ((char *)(scic_sds_stp_request_get_h2d_reg_buffer(memory))) \
120 + sizeof(SATA_FIS_REG_H2D_T) \
121 ))
122
123
124 /**
125 * This macro aligns the stp response buffer in DWORD alignment
126 */
127 #define scic_sds_stp_request_align_response_buffer(address) \
128 ((SATA_FIS_REG_D2H_T *)( \
129 (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \
130 & ~(sizeof(U32)- 1) \
131 ))
132
133 /**
134 * This macro returns the DWORD-aligned stp response buffer
135 */
136 #define scic_sds_stp_request_get_response_buffer(memory) \
137 ((SATA_FIS_REG_D2H_T *) \
138 ((char *)scic_sds_stp_request_align_response_buffer( \
139 (char *)scic_sds_stp_request_get_response_buffer_unaligned(memory) \
140 )))
141
142
143 /**
144 * This macro returns the address of the task context buffer in the io
145 * request memory
146 */
147 #define scic_sds_stp_request_get_task_context_buffer_unaligned(memory) \
148 ((SCU_TASK_CONTEXT_T *)( \
149 ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \
150 + sizeof(SCI_SSP_RESPONSE_IU_T) \
151 ))
152
153 /**
154 * This macro returns the aligned task context buffer
155 */
156 #define scic_sds_stp_request_get_task_context_buffer(memory) \
157 ((SCU_TASK_CONTEXT_T *)( \
158 ((char *)scic_sds_request_align_task_context_buffer( \
159 (char *)scic_sds_stp_request_get_task_context_buffer_unaligned(memory)) \
160 )))
161
162 /**
163 * This macro returns the address of the sgl elment pairs in the io request
164 * memory buffer
165 */
166 #define scic_sds_stp_request_get_sgl_element_buffer(memory) \
167 ((SCU_SGL_ELEMENT_PAIR_T *)( \
168 ((char *)(scic_sds_stp_request_get_task_context_buffer(memory))) \
169 + sizeof(SCU_TASK_CONTEXT_T) \
170 ))
171
172
173 /**
174 * This method return the memory space commonly required for STP IO and
175 * task requests.
176 *
177 * @return U32
178 */
179 static
180 U32 scic_sds_stp_common_request_get_object_size(void)
181 {
182 return sizeof(SCIC_SDS_STP_REQUEST_T)
183 + sizeof(SATA_FIS_REG_H2D_T)
184 + sizeof(U32)
185 + sizeof(SATA_FIS_REG_D2H_T)
186 + sizeof(U32)
187 + sizeof(SCU_TASK_CONTEXT_T)
188 + CACHE_LINE_SIZE;
189 }
190
191
192 /**
193 * This method return the memory space required for STP PIO requests.
194 *
195 * @return U32
196 */
197 U32 scic_sds_stp_request_get_object_size(void)
198 {
199 return scic_sds_stp_common_request_get_object_size()
200 + sizeof(SCU_SGL_ELEMENT_PAIR_T) * SCU_MAX_SGL_ELEMENT_PAIRS;
201 }
202
203
204 /**
205 * This method return the memory space required for STP task requests.
206 *
207 * @return U32
208 */
209 U32 scic_sds_stp_task_request_get_object_size(void)
210 {
211 return scic_sds_stp_common_request_get_object_size();
212 }
213
214
215 /**
216 *
217 *
218 * @param[in] this_request
219 */
220 void scic_sds_stp_request_assign_buffers(
221 SCIC_SDS_REQUEST_T * request
222 )
223 {
224 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
225
226 this_request->parent.command_buffer =
227 scic_sds_stp_request_get_h2d_reg_buffer(this_request);
228 this_request->parent.response_buffer =
229 scic_sds_stp_request_get_response_buffer(this_request);
230 this_request->parent.sgl_element_pair_buffer =
231 scic_sds_stp_request_get_sgl_element_buffer(this_request);
232 this_request->parent.sgl_element_pair_buffer =
233 scic_sds_request_align_sgl_element_buffer(this_request->parent.sgl_element_pair_buffer);
234
235 if (this_request->parent.was_tag_assigned_by_user == FALSE)
236 {
237 this_request->parent.task_context_buffer =
238 scic_sds_stp_request_get_task_context_buffer(this_request);
239 }
240 }
241
242 /**
243 * @brief This method is will fill in the SCU Task Context for any type of
244 * SATA request. This is called from the various SATA constructors.
245 *
246 * @pre The general io request construction is complete.
247 * @pre The buffer assignment for the command buffer is complete.
248 *
249 * @param[in] this_request The general IO request object which is to be used
250 * in constructing the SCU task context.
251 * @param[in] task_context The buffer pointer for the SCU task context which
252 * is being constructed.
253 *
254 * @return none
255 *
256 * @todo Revisit task context construction to determine what is common for
257 * SSP/SMP/STP task context structures.
258 */
259 void scu_sata_reqeust_construct_task_context(
260 SCIC_SDS_REQUEST_T * this_request,
261 SCU_TASK_CONTEXT_T * task_context
262 )
263 {
264 SCI_PHYSICAL_ADDRESS physical_address;
265 SCIC_SDS_CONTROLLER_T *owning_controller;
266 SCIC_SDS_REMOTE_DEVICE_T *target_device;
267 SCIC_SDS_PORT_T *target_port;
268
269 owning_controller = scic_sds_request_get_controller(this_request);
270 target_device = scic_sds_request_get_device(this_request);
271 target_port = scic_sds_request_get_port(this_request);
272
273 // Fill in the TC with the its required data
274 task_context->abort = 0;
275 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
276 task_context->initiator_request = 1;
277 task_context->connection_rate =
278 scic_remote_device_get_connection_rate(target_device);
279 task_context->protocol_engine_index =
280 scic_sds_controller_get_protocol_engine_group(owning_controller);
281 task_context->logical_port_index =
282 scic_sds_port_get_index(target_port);
283 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
284 task_context->valid = SCU_TASK_CONTEXT_VALID;
285 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
286
287 task_context->remote_node_index =
288 scic_sds_remote_device_get_index(this_request->target_device);
289 task_context->command_code = 0;
290
291 task_context->link_layer_control = 0;
292 task_context->do_not_dma_ssp_good_response = 1;
293 task_context->strict_ordering = 0;
294 task_context->control_frame = 0;
295 task_context->timeout_enable = 0;
296 task_context->block_guard_enable = 0;
297
298 task_context->address_modifier = 0;
299 task_context->task_phase = 0x01;
300
301 task_context->ssp_command_iu_length =
302 (sizeof(SATA_FIS_REG_H2D_T) - sizeof(U32)) / sizeof(U32);
303
304 // Set the first word of the H2D REG FIS
305 task_context->type.words[0] = *(U32 *)this_request->command_buffer;
306
307 if (this_request->was_tag_assigned_by_user)
308 {
309 // Build the task context now since we have already read the data
310 this_request->post_context = (
311 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
312 | (
313 scic_sds_controller_get_protocol_engine_group(owning_controller)
314 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
315 )
316 | (
317 scic_sds_port_get_index(target_port)
318 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
319 )
320 | scic_sds_io_tag_get_index(this_request->io_tag)
321 );
322 }
323 else
324 {
325 // Build the task context now since we have already read the data
326 this_request->post_context = (
327 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
328 | (
329 scic_sds_controller_get_protocol_engine_group(owning_controller)
330 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
331 )
332 | (
333 scic_sds_port_get_index(target_port)
334 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
335 )
336 // This is not assigned because we have to wait until we get a TCi
337 );
338 }
339
340 // Copy the physical address for the command buffer to the SCU Task Context
341 // We must offset the command buffer by 4 bytes because the first 4 bytes are
342 // transferred in the body of the TC
343 scic_cb_io_request_get_physical_address(
344 scic_sds_request_get_controller(this_request),
345 this_request,
346 ((char *)this_request->command_buffer) + sizeof(U32),
347 &physical_address
348 );
349
350 task_context->command_iu_upper =
351 sci_cb_physical_address_upper(physical_address);
352 task_context->command_iu_lower =
353 sci_cb_physical_address_lower(physical_address);
354
355 // SATA Requests do not have a response buffer
356 task_context->response_iu_upper = 0;
357 task_context->response_iu_lower = 0;
358 }
359
360 /**
361 * This method will perform any general sata request construction.
362 *
363 * @todo What part of SATA IO request construction is general?
364 *
365 * @param[in] this_request
366 *
367 * @return none
368 */
369 void scic_sds_stp_non_ncq_request_construct(
370 SCIC_SDS_REQUEST_T * this_request
371 )
372 {
373 this_request->has_started_substate_machine = TRUE;
374 }
375
376 /**
377 * This method will perform request construction common to all types of
378 * STP requests that are optimized by the silicon (i.e. UDMA, NCQ).
379 *
380 * @param[in,out] this_request This parameter specifies the request to be
381 * constructed as an optimized request.
382 * @param[in] optimized_task_type This parameter specifies whether the
383 * request is to be an UDMA request or a NCQ request.
384 * - A value of 0 indicates UDMA.
385 * - A value of 1 indicates NCQ.
386 *
387 * @return This method returns an indication as to whether the construction
388 * was successful.
389 */
390 static
391 void scic_sds_stp_optimized_request_construct(
392 SCIC_SDS_REQUEST_T * this_request,
393 U8 optimized_task_type,
394 U32 transfer_length,
395 SCI_IO_REQUEST_DATA_DIRECTION data_direction
396 )
397 {
398 SCU_TASK_CONTEXT_T * task_context = this_request->task_context_buffer;
399
400 // Build the STP task context structure
401 scu_sata_reqeust_construct_task_context(this_request, task_context);
402
403 // Copy over the number of bytes to be transferred
404 task_context->transfer_length_bytes = transfer_length;
405
406 if ( data_direction == SCI_IO_REQUEST_DATA_OUT )
407 {
408 // The difference between the DMA IN and DMA OUT request task type
409 // values are consistent with the difference between FPDMA READ
410 // and FPDMA WRITE values. Add the supplied task type parameter
411 // to this difference to set the task type properly for this
412 // DATA OUT (WRITE) case.
413 task_context->task_type = optimized_task_type + (SCU_TASK_TYPE_DMA_OUT
414 - SCU_TASK_TYPE_DMA_IN);
415 }
416 else
417 {
418 // For the DATA IN (READ) case, simply save the supplied
419 // optimized task type.
420 task_context->task_type = optimized_task_type;
421 }
422 }
423
424 /**
425 * This method performs the operations common to all SATA/STP requests
426 * utilizing the raw frame method.
427 *
428 * @param[in] this_request This parameter specifies the STP request object
429 * for which to construct a RAW command frame task context.
430 * @param[in] task_context This parameter specifies the SCU specific
431 * task context buffer to construct.
432 *
433 * @return none
434 */
435 void scu_stp_raw_request_construct_task_context(
436 SCIC_SDS_STP_REQUEST_T * this_request,
437 SCU_TASK_CONTEXT_T * task_context
438 )
439 {
440 scu_sata_reqeust_construct_task_context(&this_request->parent, task_context);
441
442 task_context->control_frame = 0;
443 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
444 task_context->task_type = SCU_TASK_TYPE_SATA_RAW_FRAME;
445 task_context->type.stp.fis_type = SATA_FIS_TYPE_REGH2D;
446 task_context->transfer_length_bytes = sizeof(SATA_FIS_REG_H2D_T) - sizeof(U32);
447 }
448
449 /**
450 * This method will construct the STP Non-data request and its associated
451 * TC data. A non-data request essentially behaves like a 0 length read
452 * request in the SCU.
453 *
454 * @param[in] this_request This parameter specifies the core request
455 * object to construction into an STP/SATA non-data request.
456 *
457 * @return This method currently always returns SCI_SUCCESS
458 */
459 SCI_STATUS scic_sds_stp_non_data_request_construct(
460 SCIC_SDS_REQUEST_T * this_request
461 )
462 {
463 scic_sds_stp_non_ncq_request_construct(this_request);
464
465 // Build the STP task context structure
466 scu_stp_raw_request_construct_task_context(
467 (SCIC_SDS_STP_REQUEST_T*) this_request,
468 this_request->task_context_buffer
469 );
470
471 sci_base_state_machine_construct(
472 &this_request->started_substate_machine,
473 &this_request->parent.parent,
474 scic_sds_stp_request_started_non_data_substate_table,
475 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
476 );
477
478 return SCI_SUCCESS;
479 }
480
481
482 SCI_STATUS scic_sds_stp_soft_reset_request_construct(
483 SCIC_SDS_REQUEST_T * this_request
484 )
485 {
486 scic_sds_stp_non_ncq_request_construct(this_request);
487
488 // Build the STP task context structure
489 scu_stp_raw_request_construct_task_context(
490 (SCIC_SDS_STP_REQUEST_T*) this_request,
491 this_request->task_context_buffer
492 );
493
494 sci_base_state_machine_construct(
495 &this_request->started_substate_machine,
496 &this_request->parent.parent,
497 scic_sds_stp_request_started_soft_reset_substate_table,
498 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
499 );
500
501 return SCI_SUCCESS;
502 }
503
504 /**
505 * @brief This method constructs the SATA request object.
506 *
507 * @param[in] this_request
508 * @param[in] sat_protocol
509 * @param[in] transfer_length
510 * @param[in] data_direction
511 * @param[in] copy_rx_frame
512 * @param[in] do_translate_sgl This parameter specifies whether SGL
513 * translation should be performed or if the user is handling
514 * it.
515 *
516 * @return SCI_STATUS
517 */
518 SCI_STATUS scic_sds_io_request_construct_sata(
519 SCIC_SDS_REQUEST_T * this_request,
520 U8 sat_protocol,
521 U32 transfer_length,
522 SCI_IO_REQUEST_DATA_DIRECTION data_direction,
523 BOOL copy_rx_frame,
524 BOOL do_translate_sgl
525 )
526 {
527 SCI_STATUS status = SCI_SUCCESS;
528
529 this_request->protocol = SCIC_STP_PROTOCOL;
530
531 this_request->sat_protocol = sat_protocol;
532
533 switch (sat_protocol)
534 {
535 case SAT_PROTOCOL_FPDMA:
536 scic_sds_stp_optimized_request_construct(
537 this_request,
538 SCU_TASK_TYPE_FPDMAQ_READ,
539 transfer_length,
540 data_direction
541 );
542
543 // Copy over the SGL elements
544 if (do_translate_sgl == TRUE)
545 scic_sds_request_build_sgl(this_request);
546 break;
547
548 case SAT_PROTOCOL_UDMA_DATA_IN:
549 case SAT_PROTOCOL_UDMA_DATA_OUT:
550 scic_sds_stp_non_ncq_request_construct(this_request);
551
552 scic_sds_stp_optimized_request_construct(
553 this_request, SCU_TASK_TYPE_DMA_IN, transfer_length, data_direction
554 );
555
556 // Copy over the SGL elements
557 if (do_translate_sgl == TRUE)
558 scic_sds_request_build_sgl(this_request);
559
560 sci_base_state_machine_construct(
561 &this_request->started_substate_machine,
562 &this_request->parent.parent,
563 scic_sds_stp_request_started_udma_substate_table,
564 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
565 );
566 break;
567
568 case SAT_PROTOCOL_PIO_DATA_IN:
569 case SAT_PROTOCOL_PIO_DATA_OUT:
570 status = scic_sds_stp_pio_request_construct(
571 this_request, sat_protocol, copy_rx_frame);
572 break;
573
574 case SAT_PROTOCOL_ATA_HARD_RESET:
575 case SAT_PROTOCOL_SOFT_RESET:
576 status = scic_sds_stp_soft_reset_request_construct(this_request);
577 break;
578
579 case SAT_PROTOCOL_NON_DATA:
580 status = scic_sds_stp_non_data_request_construct(this_request);
581 break;
582
583 #if !defined(DISABLE_ATAPI)
584 case SAT_PROTOCOL_PACKET_NON_DATA:
585 case SAT_PROTOCOL_PACKET_DMA_DATA_IN:
586 case SAT_PROTOCOL_PACKET_DMA_DATA_OUT:
587 case SAT_PROTOCOL_PACKET_PIO_DATA_IN:
588 case SAT_PROTOCOL_PACKET_PIO_DATA_OUT:
589 status = scic_sds_stp_packet_request_construct(this_request);
590 if (do_translate_sgl == TRUE)
591 scic_sds_request_build_sgl(this_request);
592 break;
593 #endif
594
595 case SAT_PROTOCOL_DMA_QUEUED:
596 case SAT_PROTOCOL_DMA:
597 case SAT_PROTOCOL_DEVICE_DIAGNOSTIC:
598 case SAT_PROTOCOL_DEVICE_RESET:
599 case SAT_PROTOCOL_RETURN_RESPONSE_INFO:
600 default:
601 SCIC_LOG_ERROR((
602 sci_base_object_get_logger(this_request),
603 SCIC_LOG_OBJECT_STP_IO_REQUEST,
604 "SCIC IO Request 0x%x received un-handled SAT Protocol %d.\n",
605 this_request, sat_protocol
606 ));
607
608 status = SCI_FAILURE;
609 break;
610 }
611
612 if (status == SCI_SUCCESS)
613 {
614 scic_sds_request_initialize_state_logging(this_request);
615
616 sci_base_state_machine_change_state(
617 &this_request->parent.state_machine,
618 SCI_BASE_REQUEST_STATE_CONSTRUCTED
619 );
620 }
621
622 return status;
623 }
624
625 //****************************************************************************
626 //* SCIC Interface Implementation
627 //****************************************************************************
628
629 void scic_stp_io_request_set_ncq_tag(
630 SCI_IO_REQUEST_HANDLE_T scic_io_request,
631 U16 ncq_tag
632 )
633 {
634 /**
635 * @note This could be made to return an error to the user if the user
636 * attempts to set the NCQ tag in the wrong state.
637 */
638 SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
639 this_request->task_context_buffer->type.stp.ncq_tag = ncq_tag;
640 }
641
642 // ---------------------------------------------------------------------------
643
644 void * scic_stp_io_request_get_h2d_reg_address(
645 SCI_IO_REQUEST_HANDLE_T scic_io_request
646 )
647 {
648 SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
649
650 return this_request->command_buffer;
651 }
652
653 // ---------------------------------------------------------------------------
654
655 void * scic_stp_io_request_get_d2h_reg_address(
656 SCI_IO_REQUEST_HANDLE_T scic_io_request
657 )
658 {
659 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)scic_io_request;
660
661 return &this_request->d2h_reg_fis;
662 }
663
664 /**
665 * Get the next SGL element from the request.
666 * - Check on which SGL element pair we are working
667 * - if working on SLG pair element A
668 * - advance to element B
669 * - else
670 * - check to see if there are more SGL element pairs
671 * for this IO request
672 * - if there are more SGL element pairs
673 * - advance to the next pair and return element A
674 *
675 * @param[in] this_request
676 *
677 * @return SCU_SGL_ELEMENT_T*
678 */
679 SCU_SGL_ELEMENT_T * scic_sds_stp_request_pio_get_next_sgl(
680 SCIC_SDS_STP_REQUEST_T * this_request
681 )
682 {
683 SCU_SGL_ELEMENT_T * current_sgl;
684
685 if (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
686 {
687 if (
688 (this_request->type.pio.request_current.sgl_pair->B.address_lower == 0)
689 && (this_request->type.pio.request_current.sgl_pair->B.address_upper == 0)
690 )
691 {
692 current_sgl = NULL;
693 }
694 else
695 {
696 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_B;
697 current_sgl = &(this_request->type.pio.request_current.sgl_pair->B);
698 }
699 }
700 else
701 {
702 if (
703 (this_request->type.pio.request_current.sgl_pair->next_pair_lower == 0)
704 && (this_request->type.pio.request_current.sgl_pair->next_pair_upper == 0)
705 )
706 {
707 current_sgl = NULL;
708 }
709 else
710 {
711 this_request->type.pio.request_current.sgl_pair =
712 scic_sds_request_get_sgl_element_pair(
713 &(this_request->parent),
714 ++this_request->type.pio.sgl_pair_index
715 );
716
717 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A;
718
719 current_sgl = &(this_request->type.pio.request_current.sgl_pair->A);
720 }
721 }
722
723 return current_sgl;
724 }
725
726 /**
727 * This method will construct the SATA PIO request.
728 *
729 * @param[in] scic_io_request The core request object which is cast to a SATA
730 * PIO request object.
731 *
732 * @return This method returns an indication as to whether the construction
733 * was successful.
734 * @retval SCI_SUCCESS Currently this method always returns this value.
735 */
736 SCI_STATUS scic_sds_stp_pio_request_construct(
737 SCIC_SDS_REQUEST_T * scic_io_request,
738 U8 sat_protocol,
739 BOOL copy_rx_frame
740 )
741 {
742 SCIC_SDS_STP_REQUEST_T * this_request;
743
744 this_request = (SCIC_SDS_STP_REQUEST_T *)scic_io_request;
745
746 scic_sds_stp_non_ncq_request_construct(&this_request->parent);
747
748 scu_stp_raw_request_construct_task_context(
749 this_request, this_request->parent.task_context_buffer
750 );
751
752 this_request->type.pio.current_transfer_bytes = 0;
753 this_request->type.pio.ending_error = 0;
754 this_request->type.pio.ending_status = 0;
755
756 this_request->type.pio.request_current.sgl_offset = 0;
757 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A;
758 this_request->type.pio.sat_protocol = sat_protocol;
759 this_request->type.pio.sgl_pair_index = 0;
760
761 if ((copy_rx_frame) || (sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT))
762 {
763 scic_sds_request_build_sgl(&this_request->parent);
764 // Since the IO request copy of the TC contains the same data as
765 // the actual TC this pointer is vaild for either.
766 this_request->type.pio.request_current.sgl_pair =
767 &this_request->parent.task_context_buffer->sgl_pair_ab;
768 }
769 else
770 {
771 // The user does not want the data copied to the SGL buffer location
772 this_request->type.pio.request_current.sgl_pair = NULL;
773 }
774
775 sci_base_state_machine_construct(
776 &this_request->parent.started_substate_machine,
777 &this_request->parent.parent.parent,
778 scic_sds_stp_request_started_pio_substate_table,
779 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
780 );
781
782 return SCI_SUCCESS;
783 }
784
785 //******************************************************************************
786 //* STP NON-DATA STATE MACHINE
787 //******************************************************************************
788
789 /**
790 * This method processes a TC completion. The expected TC completion is
791 * for the transmission of the H2D register FIS containing the SATA/STP
792 * non-data request.
793 *
794 * @param[in] this_request
795 * @param[in] completion_code
796 *
797 * @return This method always successfully processes the TC completion.
798 * @retval SCI_SUCCESS This value is always returned.
799 */
800 static
801 SCI_STATUS scic_sds_stp_request_non_data_await_h2d_tc_completion_handler(
802 SCIC_SDS_REQUEST_T * this_request,
803 U32 completion_code
804 )
805 {
806 SCIC_LOG_TRACE((
807 sci_base_object_get_logger(this_request),
808 SCIC_LOG_OBJECT_STP_IO_REQUEST,
809 "scic_sds_stp_request_non_data_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n",
810 this_request, completion_code
811 ));
812
813 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
814 {
815 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
816 scic_sds_request_set_status(
817 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
818 );
819
820 sci_base_state_machine_change_state(
821 &this_request->started_substate_machine,
822 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
823 );
824 break;
825
826 default:
827 // All other completion status cause the IO to be complete. If a NAK
828 // was received, then it is up to the user to retry the request.
829 scic_sds_request_set_status(
830 this_request,
831 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
832 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
833 );
834
835 sci_base_state_machine_change_state(
836 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
837 );
838 break;
839 }
840
841 return SCI_SUCCESS;
842 }
843
844 /**
845 * This method processes frames received from the target while waiting
846 * for a device to host register FIS. If a non-register FIS is received
847 * during this time, it is treated as a protocol violation from an
848 * IO perspective.
849 *
850 * @param[in] request This parameter specifies the request for which a
851 * frame has been received.
852 * @param[in] frame_index This parameter specifies the index of the frame
853 * that has been received.
854 *
855 * @return Indicate if the received frame was processed successfully.
856 */
857 static
858 SCI_STATUS scic_sds_stp_request_non_data_await_d2h_frame_handler(
859 SCIC_SDS_REQUEST_T * request,
860 U32 frame_index
861 )
862 {
863 SCI_STATUS status;
864 SATA_FIS_HEADER_T * frame_header;
865 U32 * frame_buffer;
866 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
867
868 // Save off the controller, so that we do not touch the request after it
869 // is completed.
870 SCIC_SDS_CONTROLLER_T * owning_controller = this_request->parent.owning_controller;
871
872 SCIC_LOG_TRACE((
873 sci_base_object_get_logger(this_request),
874 SCIC_LOG_OBJECT_STP_IO_REQUEST,
875 "scic_sds_stp_request_non_data_await_d2h_frame_handler(0x%x, 0x%x) enter\n",
876 this_request, frame_index
877 ));
878
879 status = scic_sds_unsolicited_frame_control_get_header(
880 &(owning_controller->uf_control),
881 frame_index,
882 (void**) &frame_header
883 );
884
885 if (status == SCI_SUCCESS)
886 {
887 switch (frame_header->fis_type)
888 {
889 case SATA_FIS_TYPE_REGD2H:
890 scic_sds_unsolicited_frame_control_get_buffer(
891 &(owning_controller->uf_control),
892 frame_index,
893 (void**) &frame_buffer
894 );
895
896 scic_sds_controller_copy_sata_response(
897 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer
898 );
899
900 // The command has completed with error
901 scic_sds_request_set_status(
902 &this_request->parent,
903 SCU_TASK_DONE_CHECK_RESPONSE,
904 SCI_FAILURE_IO_RESPONSE_VALID
905 );
906 break;
907
908 default:
909 SCIC_LOG_WARNING((
910 sci_base_object_get_logger(this_request),
911 SCIC_LOG_OBJECT_STP_IO_REQUEST,
912 "IO Request:0x%x Frame Id:%d protocol violation occurred\n",
913 this_request, frame_index
914 ));
915
916 scic_sds_request_set_status(
917 &this_request->parent,
918 SCU_TASK_DONE_UNEXP_FIS,
919 SCI_FAILURE_PROTOCOL_VIOLATION
920 );
921 break;
922 }
923
924 sci_base_state_machine_change_state(
925 &this_request->parent.parent.state_machine,
926 SCI_BASE_REQUEST_STATE_COMPLETED
927 );
928
929 // Frame has been decoded return it to the controller
930 scic_sds_controller_release_frame(
931 owning_controller, frame_index
932 );
933 }
934 else
935 {
936 SCIC_LOG_ERROR((
937 sci_base_object_get_logger(this_request),
938 SCIC_LOG_OBJECT_STP_IO_REQUEST,
939 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
940 this_request, frame_index, status
941 ));
942 }
943
944 return status;
945 }
946
947 // ---------------------------------------------------------------------------
948
949 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T
950 scic_sds_stp_request_started_non_data_substate_handler_table
951 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_MAX_SUBSTATES] =
952 {
953 // SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
954 {
955 {
956 scic_sds_request_default_start_handler,
957 scic_sds_request_started_state_abort_handler,
958 scic_sds_request_default_complete_handler,
959 scic_sds_request_default_destruct_handler
960 },
961 scic_sds_stp_request_non_data_await_h2d_tc_completion_handler,
962 scic_sds_request_default_event_handler,
963 scic_sds_request_default_frame_handler
964 },
965 // SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
966 {
967 {
968 scic_sds_request_default_start_handler,
969 scic_sds_request_started_state_abort_handler,
970 scic_sds_request_default_complete_handler,
971 scic_sds_request_default_destruct_handler
972 },
973 scic_sds_request_default_tc_completion_handler,
974 scic_sds_request_default_event_handler,
975 scic_sds_stp_request_non_data_await_d2h_frame_handler
976 }
977 };
978
979 static
980 void scic_sds_stp_request_started_non_data_await_h2d_completion_enter(
981 SCI_BASE_OBJECT_T *object
982 )
983 {
984 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
985
986 SET_STATE_HANDLER(
987 this_request,
988 scic_sds_stp_request_started_non_data_substate_handler_table,
989 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
990 );
991
992 scic_sds_remote_device_set_working_request(
993 this_request->target_device, this_request
994 );
995 }
996
997 static
998 void scic_sds_stp_request_started_non_data_await_d2h_enter(
999 SCI_BASE_OBJECT_T *object
1000 )
1001 {
1002 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1003
1004 SET_STATE_HANDLER(
1005 this_request,
1006 scic_sds_stp_request_started_non_data_substate_handler_table,
1007 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
1008 );
1009 }
1010
1011 // ---------------------------------------------------------------------------
1012
1013 SCI_BASE_STATE_T scic_sds_stp_request_started_non_data_substate_table
1014 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_MAX_SUBSTATES] =
1015 {
1016 {
1017 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE,
1018 scic_sds_stp_request_started_non_data_await_h2d_completion_enter,
1019 NULL
1020 },
1021 {
1022 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE,
1023 scic_sds_stp_request_started_non_data_await_d2h_enter,
1024 NULL
1025 }
1026 };
1027
1028 //******************************************************************************
1029 //* STP PIO STATE MACHINE
1030 //******************************************************************************
1031
1032 #define SCU_MAX_FRAME_BUFFER_SIZE 0x400 // 1K is the maximum SCU frame data payload
1033
1034 /**
1035 * This function will transmit DATA_FIS from (current sgl + offset) for input parameter length.
1036 * current sgl and offset is alreay stored in the IO request
1037 *
1038 * @param[in] this_request
1039 * @param[in] length
1040 *
1041 * @return SCI_STATUS
1042 */
1043 static
1044 SCI_STATUS scic_sds_stp_request_pio_data_out_trasmit_data_frame (
1045 SCIC_SDS_REQUEST_T * this_request,
1046 U32 length
1047 )
1048 {
1049 SCI_STATUS status = SCI_SUCCESS;
1050 SCU_SGL_ELEMENT_T * current_sgl;
1051 SCIC_SDS_STP_REQUEST_T * this_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *)this_request;
1052
1053 // Recycle the TC and reconstruct it for sending out DATA FIS containing
1054 // for the data from current_sgl+offset for the input length
1055 SCU_TASK_CONTEXT_T * task_context = scic_sds_controller_get_task_context_buffer(
1056 this_request->owning_controller,
1057 this_request->io_tag
1058 );
1059
1060 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
1061 {
1062 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A);
1063 }
1064 else
1065 {
1066 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B);
1067 }
1068
1069 //update the TC
1070 task_context->command_iu_upper = current_sgl->address_upper;
1071 task_context->command_iu_lower = current_sgl->address_lower;
1072 task_context->transfer_length_bytes = length;
1073 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
1074
1075 // send the new TC out.
1076 status = this_request->owning_controller->state_handlers->parent.continue_io_handler(
1077 &this_request->owning_controller->parent,
1078 &this_request->target_device->parent,
1079 &this_request->parent
1080 );
1081
1082 return status;
1083
1084 }
1085
1086 /**
1087 *
1088 *
1089 * @param[in] this_request
1090 *
1091 * @return SCI_STATUS
1092 */
1093 static
1094 SCI_STATUS scic_sds_stp_request_pio_data_out_transmit_data(
1095 SCIC_SDS_REQUEST_T * this_sds_request
1096 )
1097 {
1098
1099 SCU_SGL_ELEMENT_T * current_sgl;
1100 U32 sgl_offset;
1101 U32 remaining_bytes_in_current_sgl = 0;
1102 SCI_STATUS status = SCI_SUCCESS;
1103
1104 SCIC_SDS_STP_REQUEST_T * this_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *)this_sds_request;
1105
1106 sgl_offset = this_sds_stp_request->type.pio.request_current.sgl_offset;
1107
1108 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
1109 {
1110 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A);
1111 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->A.length - sgl_offset;
1112 }
1113 else
1114 {
1115 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B);
1116 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->B.length - sgl_offset;
1117 }
1118
1119
1120 if (this_sds_stp_request->type.pio.pio_transfer_bytes > 0)
1121 {
1122 if (this_sds_stp_request->type.pio.pio_transfer_bytes >= remaining_bytes_in_current_sgl )
1123 {
1124 //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = remaining_bytes_in_current_sgl
1125 status = scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, remaining_bytes_in_current_sgl);
1126 if (status == SCI_SUCCESS)
1127 {
1128 this_sds_stp_request->type.pio.pio_transfer_bytes -= remaining_bytes_in_current_sgl;
1129 sgl_offset = 0;
1130 }
1131 }
1132 else if (this_sds_stp_request->type.pio.pio_transfer_bytes < remaining_bytes_in_current_sgl )
1133 {
1134 //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = type.pio.pio_transfer_bytes
1135 scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, this_sds_stp_request->type.pio.pio_transfer_bytes);
1136
1137 if (status == SCI_SUCCESS)
1138 {
1139 //Sgl offset will be adjusted and saved for future
1140 sgl_offset += this_sds_stp_request->type.pio.pio_transfer_bytes;
1141 current_sgl->address_lower += this_sds_stp_request->type.pio.pio_transfer_bytes;
1142 this_sds_stp_request->type.pio.pio_transfer_bytes = 0;
1143 }
1144 }
1145 }
1146
1147 if (status == SCI_SUCCESS)
1148 {
1149 this_sds_stp_request->type.pio.request_current.sgl_offset = sgl_offset;
1150 }
1151
1152 return status;
1153 }
1154
1155 /**
1156 * Copy the data from the buffer for the length specified to the IO reqeust
1157 * SGL specified data region.
1158 *
1159 * @param[in] this_request The request that is used for the SGL processing.
1160 * @param[in] data_buffer The buffer of data to be copied.
1161 * @param[in] length The length of the data transfer.
1162 *
1163 * @return SCI_STATUS
1164 */
1165 static
1166 SCI_STATUS scic_sds_stp_request_pio_data_in_copy_data_buffer(
1167 SCIC_SDS_STP_REQUEST_T * this_request,
1168 U8 * data_buffer,
1169 U32 length
1170 )
1171 {
1172 SCI_STATUS status;
1173 SCU_SGL_ELEMENT_T * current_sgl;
1174 U32 sgl_offset;
1175 U32 data_offset;
1176 U8 * source_address;
1177
1178 // Initial setup to get the current working SGL and the offset within the buffer
1179 current_sgl =
1180 (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) ?
1181 &(this_request->type.pio.request_current.sgl_pair->A) :
1182 &(this_request->type.pio.request_current.sgl_pair->B) ;
1183
1184 sgl_offset = this_request->type.pio.request_current.sgl_offset;
1185
1186 source_address = data_buffer;
1187 data_offset = this_request->type.pio.current_transfer_bytes;
1188 status = SCI_SUCCESS;
1189
1190 // While we are still doing Ok and there is more data to transfer
1191 while (
1192 (length > 0)
1193 && (status == SCI_SUCCESS)
1194 )
1195 {
1196 if (current_sgl->length == sgl_offset)
1197 {
1198 // This SGL has been exauhasted so we need to get the next SGL
1199 current_sgl = scic_sds_stp_request_pio_get_next_sgl(this_request);
1200
1201 if (current_sgl == NULL)
1202 status = SCI_FAILURE;
1203 else
1204 sgl_offset = 0;
1205 }
1206 else
1207 {
1208 #ifdef ENABLE_OSSL_COPY_BUFFER
1209 scic_cb_io_request_copy_buffer(this_request, data_buffer, data_offset, length);
1210 length = 0;
1211 #else
1212 U8 * destination_address;
1213 U32 copy_length;
1214
1215 destination_address = (U8 *)scic_cb_io_request_get_virtual_address_from_sgl(
1216 this_request,
1217 data_offset
1218 );
1219
1220 copy_length = MIN(length, current_sgl->length - sgl_offset);
1221
1222 memcpy(destination_address, source_address, copy_length);
1223
1224 length -= copy_length;
1225 sgl_offset += copy_length;
1226 data_offset += copy_length;
1227 source_address += copy_length;
1228 #endif
1229 }
1230 }
1231
1232 this_request->type.pio.request_current.sgl_offset = sgl_offset;
1233
1234 return status;
1235 }
1236
1237 /**
1238 * Copy the data buffer to the io request data region.
1239 *
1240 * @param[in] this_request The PIO DATA IN request that is to receive the
1241 * data.
1242 * @param[in] data_buffer The buffer to copy from.
1243 *
1244 * @return SCI_STATUS
1245 */
1246 static
1247 SCI_STATUS scic_sds_stp_request_pio_data_in_copy_data(
1248 SCIC_SDS_STP_REQUEST_T * this_request,
1249 U8 * data_buffer
1250 )
1251 {
1252 SCI_STATUS status;
1253
1254 // If there is less than 1K remaining in the transfer request
1255 // copy just the data for the transfer
1256 if (this_request->type.pio.pio_transfer_bytes < SCU_MAX_FRAME_BUFFER_SIZE)
1257 {
1258 status = scic_sds_stp_request_pio_data_in_copy_data_buffer(
1259 this_request,data_buffer,this_request->type.pio.pio_transfer_bytes);
1260
1261 if (status == SCI_SUCCESS)
1262 {
1263 // All data for this PIO request has now been copied, so we don't
1264 // technically need to update current_transfer_bytes here - just
1265 // doing it for completeness.
1266 this_request->type.pio.current_transfer_bytes += this_request->type.pio.pio_transfer_bytes;
1267 this_request->type.pio.pio_transfer_bytes = 0;
1268 }
1269 }
1270 else
1271 {
1272 // We are transferring the whole frame so copy
1273 status = scic_sds_stp_request_pio_data_in_copy_data_buffer(
1274 this_request, data_buffer, SCU_MAX_FRAME_BUFFER_SIZE);
1275
1276 if (status == SCI_SUCCESS)
1277 {
1278 this_request->type.pio.pio_transfer_bytes -= SCU_MAX_FRAME_BUFFER_SIZE;
1279 this_request->type.pio.current_transfer_bytes += SCU_MAX_FRAME_BUFFER_SIZE;
1280 }
1281 }
1282
1283 return status;
1284 }
1285
1286 /**
1287 *
1288 *
1289 * @param[in] this_request
1290 * @param[in] completion_code
1291 *
1292 * @return SCI_STATUS
1293 */
1294 static
1295 SCI_STATUS scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler(
1296 SCIC_SDS_REQUEST_T * this_request,
1297 U32 completion_code
1298 )
1299 {
1300 SCI_STATUS status = SCI_SUCCESS;
1301
1302 SCIC_LOG_TRACE((
1303 sci_base_object_get_logger(this_request),
1304 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1305 "scic_sds_stp_request_pio_data_in_await_h2d_completion_tc_completion_handler(0x%x, 0x%x) enter\n",
1306 this_request, completion_code
1307 ));
1308
1309 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
1310 {
1311 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1312 scic_sds_request_set_status(
1313 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1314 );
1315
1316 sci_base_state_machine_change_state(
1317 &this_request->started_substate_machine,
1318 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1319 );
1320 break;
1321
1322 default:
1323 // All other completion status cause the IO to be complete. If a NAK
1324 // was received, then it is up to the user to retry the request.
1325 scic_sds_request_set_status(
1326 this_request,
1327 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1328 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1329 );
1330
1331 sci_base_state_machine_change_state(
1332 &this_request->parent.state_machine,
1333 SCI_BASE_REQUEST_STATE_COMPLETED
1334 );
1335 break;
1336 }
1337
1338 return status;
1339 }
1340
1341 /**
1342 *
1343 *
1344 * @param[in] this_request
1345 * @param[in] frame_index
1346 *
1347 * @return SCI_STATUS
1348 */
1349 static
1350 SCI_STATUS scic_sds_stp_request_pio_await_frame_frame_handler(
1351 SCIC_SDS_REQUEST_T * request,
1352 U32 frame_index
1353 )
1354 {
1355 SCI_STATUS status;
1356 SATA_FIS_HEADER_T * frame_header;
1357 U32 * frame_buffer;
1358 SCIC_SDS_STP_REQUEST_T * this_request;
1359 SCIC_SDS_CONTROLLER_T * owning_controller;
1360
1361 this_request = (SCIC_SDS_STP_REQUEST_T *)request;
1362
1363 // Save off the controller, so that we do not touch the request after it
1364 // is completed.
1365 owning_controller = this_request->parent.owning_controller;
1366
1367 SCIC_LOG_TRACE((
1368 sci_base_object_get_logger(this_request),
1369 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1370 "scic_sds_stp_request_pio_data_in_await_frame_frame_handler(0x%x, 0x%x) enter\n",
1371 this_request, frame_index
1372 ));
1373
1374 status = scic_sds_unsolicited_frame_control_get_header(
1375 &(owning_controller->uf_control),
1376 frame_index,
1377 (void**) &frame_header
1378 );
1379
1380 if (status == SCI_SUCCESS)
1381 {
1382 switch (frame_header->fis_type)
1383 {
1384 case SATA_FIS_TYPE_PIO_SETUP:
1385 // Get from the frame buffer the PIO Setup Data
1386 scic_sds_unsolicited_frame_control_get_buffer(
1387 &(owning_controller->uf_control),
1388 frame_index,
1389 (void**) &frame_buffer
1390 );
1391
1392 // Get the data from the PIO Setup
1393 // The SCU Hardware returns first word in the frame_header and the rest
1394 // of the data is in the frame buffer so we need to back up one dword
1395 this_request->type.pio.pio_transfer_bytes =
1396 (U16)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->transfter_count;
1397 this_request->type.pio.ending_status =
1398 (U8)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->ending_status;
1399
1400 scic_sds_controller_copy_sata_response(
1401 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer
1402 );
1403
1404 this_request->d2h_reg_fis.status =
1405 this_request->type.pio.ending_status;
1406
1407 //The next state is dependent on whether the request was PIO Data-in or Data out
1408 if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_IN)
1409 {
1410 sci_base_state_machine_change_state(
1411 &this_request->parent.started_substate_machine,
1412 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1413 );
1414 }
1415 else if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT)
1416 {
1417 //Transmit data
1418 status = scic_sds_stp_request_pio_data_out_transmit_data ( request);
1419 if (status == SCI_SUCCESS)
1420 {
1421 sci_base_state_machine_change_state(
1422 &this_request->parent.started_substate_machine,
1423 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1424 );
1425 }
1426 }
1427 break;
1428
1429 case SATA_FIS_TYPE_SETDEVBITS:
1430 sci_base_state_machine_change_state(
1431 &this_request->parent.started_substate_machine,
1432 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1433 );
1434 break;
1435
1436 case SATA_FIS_TYPE_REGD2H:
1437 if ( (frame_header->status & ATA_STATUS_REG_BSY_BIT) == 0)
1438 {
1439 scic_sds_unsolicited_frame_control_get_buffer(
1440 &(owning_controller->uf_control),
1441 frame_index,
1442 (void**) &frame_buffer
1443 );
1444
1445 scic_sds_controller_copy_sata_response(
1446 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer);
1447
1448 scic_sds_request_set_status(
1449 &this_request->parent,
1450 SCU_TASK_DONE_CHECK_RESPONSE,
1451 SCI_FAILURE_IO_RESPONSE_VALID
1452 );
1453
1454 sci_base_state_machine_change_state(
1455 &this_request->parent.parent.state_machine,
1456 SCI_BASE_REQUEST_STATE_COMPLETED
1457 );
1458 }
1459 else
1460 {
1461 // Now why is the drive sending a D2H Register FIS when it is still busy?
1462 // Do nothing since we are still in the right state.
1463 SCIC_LOG_INFO((
1464 sci_base_object_get_logger(this_request),
1465 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1466 "SCIC PIO Request 0x%x received D2H Register FIS with BSY status 0x%x\n",
1467 this_request, frame_header->status
1468 ));
1469 }
1470 break;
1471
1472 default:
1473 break;
1474 }
1475
1476 // Frame is decoded return it to the controller
1477 scic_sds_controller_release_frame(
1478 owning_controller,
1479 frame_index
1480 );
1481 }
1482 else
1483 {
1484 SCIC_LOG_ERROR((
1485 sci_base_object_get_logger(this_request),
1486 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1487 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
1488 this_request, frame_index, status
1489 ));
1490 }
1491
1492 return status;
1493 }
1494
1495 /**
1496 *
1497 *
1498 * @param[in] this_request
1499 * @param[in] frame_index
1500 *
1501 * @return SCI_STATUS
1502 */
1503 static
1504 SCI_STATUS scic_sds_stp_request_pio_data_in_await_data_frame_handler(
1505 SCIC_SDS_REQUEST_T * request,
1506 U32 frame_index
1507 )
1508 {
1509 SCI_STATUS status;
1510 SATA_FIS_HEADER_T * frame_header;
1511 SATA_FIS_DATA_T * frame_buffer;
1512 SCIC_SDS_STP_REQUEST_T * this_request;
1513 SCIC_SDS_CONTROLLER_T * owning_controller;
1514
1515 this_request = (SCIC_SDS_STP_REQUEST_T *)request;
1516
1517 // Save off the controller, so that we do not touch the request after it
1518 // is completed.
1519 owning_controller = this_request->parent.owning_controller;
1520
1521 SCIC_LOG_TRACE((
1522 sci_base_object_get_logger(this_request),
1523 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1524 "scic_sds_stp_request_pio_data_in_await_data_frame_handler(0x%x, 0x%x) enter\n",
1525 this_request, frame_index
1526 ));
1527
1528 status = scic_sds_unsolicited_frame_control_get_header(
1529 &(owning_controller->uf_control),
1530 frame_index,
1531 (void**) &frame_header
1532 );
1533
1534 if (status == SCI_SUCCESS)
1535 {
1536 if (frame_header->fis_type == SATA_FIS_TYPE_DATA)
1537 {
1538 if (this_request->type.pio.request_current.sgl_pair == NULL)
1539 {
1540 this_request->parent.saved_rx_frame_index = frame_index;
1541 this_request->type.pio.pio_transfer_bytes = 0;
1542 }
1543 else
1544 {
1545 status = scic_sds_unsolicited_frame_control_get_buffer(
1546 &(owning_controller->uf_control),
1547 frame_index,
1548 (void**) &frame_buffer
1549 );
1550
1551 status = scic_sds_stp_request_pio_data_in_copy_data(this_request, (U8 *)frame_buffer);
1552
1553 // Frame is decoded return it to the controller
1554 scic_sds_controller_release_frame(
1555 owning_controller,
1556 frame_index
1557 );
1558 }
1559
1560 // Check for the end of the transfer, are there more bytes remaining
1561 // for this data transfer
1562 if (
1563 (status == SCI_SUCCESS)
1564 && (this_request->type.pio.pio_transfer_bytes == 0)
1565 )
1566 {
1567 if ((this_request->type.pio.ending_status & ATA_STATUS_REG_BSY_BIT) == 0)
1568 {
1569 scic_sds_request_set_status(
1570 &this_request->parent,
1571 SCU_TASK_DONE_CHECK_RESPONSE,
1572 SCI_FAILURE_IO_RESPONSE_VALID
1573 );
1574
1575 sci_base_state_machine_change_state(
1576 &this_request->parent.parent.state_machine,
1577 SCI_BASE_REQUEST_STATE_COMPLETED
1578 );
1579 }
1580 else
1581 {
1582 sci_base_state_machine_change_state(
1583 &this_request->parent.started_substate_machine,
1584 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1585 );
1586 }
1587 }
1588 }
1589 else
1590 {
1591 SCIC_LOG_ERROR((
1592 sci_base_object_get_logger(this_request),
1593 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1594 "SCIC PIO Request 0x%x received frame %d with fis type 0x%02x when expecting a data fis.\n",
1595 this_request, frame_index, frame_header->fis_type
1596 ));
1597
1598 scic_sds_request_set_status(
1599 &this_request->parent,
1600 SCU_TASK_DONE_GOOD,
1601 SCI_FAILURE_IO_REQUIRES_SCSI_ABORT
1602 );
1603
1604 sci_base_state_machine_change_state(
1605 &this_request->parent.parent.state_machine,
1606 SCI_BASE_REQUEST_STATE_COMPLETED
1607 );
1608
1609 // Frame is decoded return it to the controller
1610 scic_sds_controller_release_frame(
1611 owning_controller,
1612 frame_index
1613 );
1614 }
1615 }
1616 else
1617 {
1618 SCIC_LOG_ERROR((
1619 sci_base_object_get_logger(this_request),
1620 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1621 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
1622 this_request, frame_index, status
1623 ));
1624 }
1625
1626 return status;
1627 }
1628
1629
1630 /**
1631 *
1632 *
1633 * @param[in] this_request
1634 * @param[in] completion_code
1635 *
1636 * @return SCI_STATUS
1637 */
1638 static
1639 SCI_STATUS scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler(
1640
1641 SCIC_SDS_REQUEST_T * this_request,
1642 U32 completion_code
1643 )
1644 {
1645 SCI_STATUS status = SCI_SUCCESS;
1646 BOOL all_frames_transferred = FALSE;
1647
1648 SCIC_SDS_STP_REQUEST_T *this_scic_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *) this_request;
1649
1650 SCIC_LOG_TRACE((
1651 sci_base_object_get_logger(this_request),
1652 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1653 "scic_sds_stp_request_pio_data_in_await_h2d_completion_tc_completion_handler(0x%x, 0x%x) enter\n",
1654 this_request, completion_code
1655 ));
1656
1657 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
1658 {
1659 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1660 //Transmit data
1661 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes != 0)
1662 {
1663 status = scic_sds_stp_request_pio_data_out_transmit_data ( this_request);
1664 if (status == SCI_SUCCESS)
1665 {
1666 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0)
1667 all_frames_transferred = TRUE;
1668 }
1669 }
1670 else if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0)
1671 {
1672 //this will happen if the all data is written at the first time after the pio setup fis is received
1673 all_frames_transferred = TRUE;
1674 }
1675
1676 //all data transferred.
1677 if (all_frames_transferred)
1678 {
1679 //Change the state to SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_FRAME_SUBSTATE
1680 //and wait for PIO_SETUP fis / or D2H REg fis.
1681 sci_base_state_machine_change_state(
1682 &this_request->started_substate_machine,
1683 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1684 );
1685 }
1686 break;
1687
1688 default:
1689 // All other completion status cause the IO to be complete. If a NAK
1690 // was received, then it is up to the user to retry the request.
1691 scic_sds_request_set_status(
1692 this_request,
1693 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1694 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1695 );
1696
1697 sci_base_state_machine_change_state(
1698 &this_request->parent.state_machine,
1699 SCI_BASE_REQUEST_STATE_COMPLETED
1700 );
1701 break;
1702 }
1703
1704 return status;
1705 }
1706
1707 /**
1708 * This method will handle any link layer events while waiting for the data
1709 * frame.
1710 *
1711 * @param[in] request This is the request which is receiving the event.
1712 * @param[in] event_code This is the event code that the request on which the
1713 * request is expected to take action.
1714 *
1715 * @return SCI_STATUS
1716 * @retval SCI_SUCCESS
1717 * @retval SCI_FAILURE
1718 */
1719 static
1720 SCI_STATUS scic_sds_stp_request_pio_data_in_await_data_event_handler(
1721 SCIC_SDS_REQUEST_T * request,
1722 U32 event_code
1723 )
1724 {
1725 SCI_STATUS status;
1726
1727 switch (scu_get_event_specifier(event_code))
1728 {
1729 case SCU_TASK_DONE_CRC_ERR << SCU_EVENT_SPECIFIC_CODE_SHIFT:
1730 // We are waiting for data and the SCU has R_ERR the data frame.
1731 // Go back to waiting for the D2H Register FIS
1732 sci_base_state_machine_change_state(
1733 &request->started_substate_machine,
1734 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1735 );
1736
1737 status = SCI_SUCCESS;
1738 break;
1739
1740 default:
1741 SCIC_LOG_ERROR((
1742 sci_base_object_get_logger(request),
1743 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1744 "SCIC PIO Request 0x%x received unexpected event 0x%08x\n",
1745 request, event_code
1746 ));
1747
1748 /// @todo Should we fail the PIO request when we get an unexpected event?
1749 status = SCI_FAILURE;
1750 break;
1751 }
1752
1753 return status;
1754 }
1755
1756 // ---------------------------------------------------------------------------
1757
1758 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T
1759 scic_sds_stp_request_started_pio_substate_handler_table
1760 [SCIC_SDS_STP_REQUEST_STARTED_PIO_MAX_SUBSTATES] =
1761 {
1762 // SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
1763 {
1764 {
1765 scic_sds_request_default_start_handler,
1766 scic_sds_request_started_state_abort_handler,
1767 scic_sds_request_default_complete_handler,
1768 scic_sds_request_default_destruct_handler
1769 },
1770 scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler,
1771 scic_sds_request_default_event_handler,
1772 scic_sds_request_default_frame_handler
1773 },
1774 // SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1775 {
1776 {
1777 scic_sds_request_default_start_handler,
1778 //scic_sds_stp_pio_request_data_in_await_frame_abort_handler,
1779 scic_sds_request_started_state_abort_handler,
1780 scic_sds_request_default_complete_handler,
1781 scic_sds_request_default_destruct_handler
1782 },
1783 scic_sds_request_default_tc_completion_handler,
1784 scic_sds_request_default_event_handler,
1785 scic_sds_stp_request_pio_await_frame_frame_handler
1786 },
1787 // SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1788 {
1789 {
1790 scic_sds_request_default_start_handler,
1791 //scic_sds_stp_pio_request_data_in_await_data_abort_handler,
1792 scic_sds_request_started_state_abort_handler,
1793 scic_sds_request_default_complete_handler,
1794 scic_sds_request_default_destruct_handler
1795 },
1796 scic_sds_request_default_tc_completion_handler,
1797 scic_sds_stp_request_pio_data_in_await_data_event_handler,
1798 scic_sds_stp_request_pio_data_in_await_data_frame_handler
1799 },
1800 //SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1801 {
1802 {
1803 scic_sds_request_default_start_handler,
1804 scic_sds_request_started_state_abort_handler,
1805 scic_sds_request_default_complete_handler,
1806 scic_sds_request_default_destruct_handler
1807 },
1808 scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler,
1809 scic_sds_request_default_event_handler,
1810 scic_sds_request_default_frame_handler
1811 }
1812 };
1813
1814 static
1815 void scic_sds_stp_request_started_pio_await_h2d_completion_enter(
1816 SCI_BASE_OBJECT_T *object
1817 )
1818 {
1819 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1820
1821 SET_STATE_HANDLER(
1822 this_request,
1823 scic_sds_stp_request_started_pio_substate_handler_table,
1824 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
1825 );
1826
1827 scic_sds_remote_device_set_working_request(
1828 this_request->target_device, this_request);
1829 }
1830
1831 static
1832 void scic_sds_stp_request_started_pio_await_frame_enter(
1833 SCI_BASE_OBJECT_T *object
1834 )
1835 {
1836 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1837
1838 SET_STATE_HANDLER(
1839 this_request,
1840 scic_sds_stp_request_started_pio_substate_handler_table,
1841 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1842 );
1843 }
1844
1845 static
1846 void scic_sds_stp_request_started_pio_data_in_await_data_enter(
1847 SCI_BASE_OBJECT_T *object
1848 )
1849 {
1850 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1851
1852 SET_STATE_HANDLER(
1853 this_request,
1854 scic_sds_stp_request_started_pio_substate_handler_table,
1855 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1856 );
1857 }
1858
1859 static
1860 void scic_sds_stp_request_started_pio_data_out_transmit_data_enter(
1861 SCI_BASE_OBJECT_T *object
1862 )
1863 {
1864 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1865
1866 SET_STATE_HANDLER(
1867 this_request,
1868 scic_sds_stp_request_started_pio_substate_handler_table,
1869 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1870 );
1871 }
1872
1873 // ---------------------------------------------------------------------------
1874
1875 SCI_BASE_STATE_T
1876 scic_sds_stp_request_started_pio_substate_table
1877 [SCIC_SDS_STP_REQUEST_STARTED_PIO_MAX_SUBSTATES] =
1878 {
1879 {
1880 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE,
1881 scic_sds_stp_request_started_pio_await_h2d_completion_enter,
1882 NULL
1883 },
1884 {
1885 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE,
1886 scic_sds_stp_request_started_pio_await_frame_enter,
1887 NULL
1888 },
1889 {
1890 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE,
1891 scic_sds_stp_request_started_pio_data_in_await_data_enter,
1892 NULL
1893 },
1894 {
1895 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE,
1896 scic_sds_stp_request_started_pio_data_out_transmit_data_enter,
1897 NULL
1898 }
1899 };
1900
1901 //******************************************************************************
1902 //* UDMA REQUEST STATE MACHINE
1903 //******************************************************************************
1904
1905 static
1906 void scic_sds_stp_request_udma_complete_request(
1907 SCIC_SDS_REQUEST_T * this_request,
1908 U32 scu_status,
1909 SCI_STATUS sci_status
1910 )
1911 {
1912 scic_sds_request_set_status(
1913 this_request, scu_status, sci_status
1914 );
1915
1916 sci_base_state_machine_change_state(
1917 &this_request->parent.state_machine,
1918 SCI_BASE_REQUEST_STATE_COMPLETED
1919 );
1920 }
1921
1922 /**
1923 *
1924 *
1925 * @param[in] this_request
1926 * @param[in] frame_index
1927 *
1928 * @return SCI_STATUS
1929 */
1930 static
1931 SCI_STATUS scic_sds_stp_request_udma_general_frame_handler(
1932 SCIC_SDS_REQUEST_T * this_request,
1933 U32 frame_index
1934 )
1935 {
1936 SCI_STATUS status;
1937 SATA_FIS_HEADER_T * frame_header;
1938 U32 * frame_buffer;
1939
1940 SCIC_LOG_TRACE((
1941 sci_base_object_get_logger(this_request),
1942 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1943 "scic_sds_stp_pio_request_data_in_await_frame_frame_handler(0x%x, 0x%x) enter\n",
1944 this_request, frame_index
1945 ));
1946
1947 status = scic_sds_unsolicited_frame_control_get_header(
1948 &this_request->owning_controller->uf_control,
1949 frame_index,
1950 (void**) &frame_header
1951 );
1952
1953 if (
1954 (status == SCI_SUCCESS)
1955 && (frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
1956 )
1957 {
1958 scic_sds_unsolicited_frame_control_get_buffer(
1959 &this_request->owning_controller->uf_control,
1960 frame_index,
1961 (void**) &frame_buffer
1962 );
1963
1964 scic_sds_controller_copy_sata_response(
1965 &((SCIC_SDS_STP_REQUEST_T *)this_request)->d2h_reg_fis,
1966 (U32 *)frame_header,
1967 frame_buffer
1968 );
1969 }
1970
1971 scic_sds_controller_release_frame(
1972 this_request->owning_controller, frame_index);
1973
1974 return status;
1975 }
1976
1977 /**
1978 * @brief This method process TC completions while in the state where
1979 * we are waiting for TC completions.
1980 *
1981 * @param[in] this_request
1982 * @param[in] completion_code
1983 *
1984 * @return SCI_STATUS
1985 */
1986 static
1987 SCI_STATUS scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler(
1988 SCIC_SDS_REQUEST_T * request,
1989 U32 completion_code
1990 )
1991 {
1992 SCI_STATUS status = SCI_SUCCESS;
1993 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
1994
1995 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
1996 {
1997 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1998 scic_sds_stp_request_udma_complete_request(
1999 &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2000 );
2001 break;
2002
2003 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS):
2004 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
2005 // We must check ther response buffer to see if the D2H Register FIS was
2006 // received before we got the TC completion.
2007 if (this_request->d2h_reg_fis.fis_type == SATA_FIS_TYPE_REGD2H)
2008 {
2009 scic_sds_remote_device_suspend(
2010 this_request->parent.target_device,
2011 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))
2012 );
2013
2014 scic_sds_stp_request_udma_complete_request(
2015 &this_request->parent,
2016 SCU_TASK_DONE_CHECK_RESPONSE,
2017 SCI_FAILURE_IO_RESPONSE_VALID
2018 );
2019 }
2020 else
2021 {
2022 // If we have an error completion status for the TC then we can expect a
2023 // D2H register FIS from the device so we must change state to wait for it
2024 sci_base_state_machine_change_state(
2025 &this_request->parent.started_substate_machine,
2026 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
2027 );
2028 }
2029 break;
2030
2031 /// @todo Check to see if any of these completion status need to wait for
2032 /// the device to host register fis.
2033 /// @todo We can retry the command for SCU_TASK_DONE_CMD_LL_R_ERR - this comes only for B0
2034 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN):
2035 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
2036 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR):
2037 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR):
2038 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR):
2039 scic_sds_remote_device_suspend(
2040 this_request->parent.target_device,
2041 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))
2042 );
2043 // Fall through to the default case
2044 default:
2045 // All other completion status cause the IO to be complete.
2046 SCIC_LOG_ERROR((
2047 sci_base_object_get_logger(&this_request->parent),
2048 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2049 "SCIC IO Request 0x%x returning CONTROLLER_SPECIFIC_IO_ERR for completion code 0x%x\n",
2050 &this_request->parent, completion_code
2051 ));
2052 scic_sds_stp_request_udma_complete_request(
2053 &this_request->parent,
2054 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
2055 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2056 );
2057 break;
2058 }
2059
2060 return status;
2061 }
2062
2063 static
2064 SCI_STATUS scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler(
2065 SCIC_SDS_REQUEST_T * this_request,
2066 U32 frame_index
2067 )
2068 {
2069 SCI_STATUS status;
2070
2071 // Use the general frame handler to copy the resposne data
2072 status = scic_sds_stp_request_udma_general_frame_handler(this_request, frame_index);
2073
2074 if (status == SCI_SUCCESS)
2075 {
2076 scic_sds_stp_request_udma_complete_request(
2077 this_request,
2078 SCU_TASK_DONE_CHECK_RESPONSE,
2079 SCI_FAILURE_IO_RESPONSE_VALID
2080 );
2081 }
2082
2083 return status;
2084 }
2085
2086 // ---------------------------------------------------------------------------
2087
2088 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T
2089 scic_sds_stp_request_started_udma_substate_handler_table
2090 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_MAX_SUBSTATES] =
2091 {
2092 // SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
2093 {
2094 {
2095 scic_sds_request_default_start_handler,
2096 scic_sds_request_started_state_abort_handler,
2097 scic_sds_request_default_complete_handler,
2098 scic_sds_request_default_destruct_handler
2099 },
2100 scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler,
2101 scic_sds_request_default_event_handler,
2102 scic_sds_stp_request_udma_general_frame_handler
2103 },
2104 // SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
2105 {
2106 {
2107 scic_sds_request_default_start_handler,
2108 scic_sds_request_started_state_abort_handler,
2109 scic_sds_request_default_complete_handler,
2110 scic_sds_request_default_destruct_handler
2111 },
2112 scic_sds_request_default_tc_completion_handler,
2113 scic_sds_request_default_event_handler,
2114 scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler
2115 }
2116 };
2117
2118 /**
2119 *
2120 *
2121 * @param[in] object
2122 */
2123 static
2124 void scic_sds_stp_request_started_udma_await_tc_completion_enter(
2125 SCI_BASE_OBJECT_T *object
2126 )
2127 {
2128 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2129
2130 SET_STATE_HANDLER(
2131 this_request,
2132 scic_sds_stp_request_started_udma_substate_handler_table,
2133 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
2134 );
2135 }
2136
2137 /**
2138 * This state is entered when there is an TC completion failure. The hardware
2139 * received an unexpected condition while processing the IO request and now
2140 * will UF the D2H register FIS to complete the IO.
2141 *
2142 * @param[in] object
2143 */
2144 static
2145 void scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter(
2146 SCI_BASE_OBJECT_T *object
2147 )
2148 {
2149 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2150
2151 SET_STATE_HANDLER(
2152 this_request,
2153 scic_sds_stp_request_started_udma_substate_handler_table,
2154 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
2155 );
2156 }
2157
2158 // ---------------------------------------------------------------------------
2159
2160 SCI_BASE_STATE_T
2161 scic_sds_stp_request_started_udma_substate_table
2162 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_MAX_SUBSTATES] =
2163 {
2164 {
2165 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE,
2166 scic_sds_stp_request_started_udma_await_tc_completion_enter,
2167 NULL
2168 },
2169 {
2170 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE,
2171 scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter,
2172 NULL
2173 }
2174 };
2175
2176 //******************************************************************************
2177 //* STP SOFT RESET STATE MACHINE
2178 //******************************************************************************
2179
2180 /**
2181 * This method processes a TC completion. The expected TC completion is
2182 * for the transmission of the H2D register FIS containing the SATA/STP
2183 * non-data request.
2184 *
2185 * @param[in] this_request
2186 * @param[in] completion_code
2187 *
2188 * @return This method always successfully processes the TC completion.
2189 * @retval SCI_SUCCESS This value is always returned.
2190 */
2191 static
2192 SCI_STATUS scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler(
2193 SCIC_SDS_REQUEST_T * this_request,
2194 U32 completion_code
2195 )
2196 {
2197 SCIC_LOG_TRACE((
2198 sci_base_object_get_logger(this_request),
2199 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2200 "scic_sds_stp_request_soft_reset_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n",
2201 this_request, completion_code
2202 ));
2203
2204 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
2205 {
2206 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
2207 scic_sds_request_set_status(
2208 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2209 );
2210
2211 sci_base_state_machine_change_state(
2212 &this_request->started_substate_machine,
2213 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
2214 );
2215 break;
2216
2217 default:
2218 // All other completion status cause the IO to be complete. If a NAK
2219 // was received, then it is up to the user to retry the request.
2220 scic_sds_request_set_status(
2221 this_request,
2222 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
2223 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2224 );
2225
2226 sci_base_state_machine_change_state(
2227 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
2228 );
2229 break;
2230 }
2231
2232 return SCI_SUCCESS;
2233 }
2234
2235 /**
2236 * This method processes a TC completion. The expected TC completion is
2237 * for the transmission of the H2D register FIS containing the SATA/STP
2238 * non-data request.
2239 *
2240 * @param[in] this_request
2241 * @param[in] completion_code
2242 *
2243 * @return This method always successfully processes the TC completion.
2244 * @retval SCI_SUCCESS This value is always returned.
2245 */
2246 static
2247 SCI_STATUS scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler(
2248 SCIC_SDS_REQUEST_T * this_request,
2249 U32 completion_code
2250 )
2251 {
2252 SCIC_LOG_TRACE((
2253 sci_base_object_get_logger(this_request),
2254 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2255 "scic_sds_stp_request_soft_reset_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n",
2256 this_request, completion_code
2257 ));
2258
2259 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
2260 {
2261 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
2262 scic_sds_request_set_status(
2263 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2264 );
2265
2266 sci_base_state_machine_change_state(
2267 &this_request->started_substate_machine,
2268 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
2269 );
2270 break;
2271
2272 default:
2273 // All other completion status cause the IO to be complete. If a NAK
2274 // was received, then it is up to the user to retry the request.
2275 scic_sds_request_set_status(
2276 this_request,
2277 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
2278 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2279 );
2280
2281 sci_base_state_machine_change_state(
2282 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
2283 );
2284 break;
2285 }
2286
2287 return SCI_SUCCESS;
2288 }
2289
2290 /**
2291 * This method processes frames received from the target while waiting
2292 * for a device to host register FIS. If a non-register FIS is received
2293 * during this time, it is treated as a protocol violation from an
2294 * IO perspective.
2295 *
2296 * @param[in] request This parameter specifies the request for which a
2297 * frame has been received.
2298 * @param[in] frame_index This parameter specifies the index of the frame
2299 * that has been received.
2300 *
2301 * @return Indicate if the received frame was processed successfully.
2302 */
2303 static
2304 SCI_STATUS scic_sds_stp_request_soft_reset_await_d2h_frame_handler(
2305 SCIC_SDS_REQUEST_T * request,
2306 U32 frame_index
2307 )
2308 {
2309 SCI_STATUS status;
2310 SATA_FIS_HEADER_T * frame_header;
2311 U32 * frame_buffer;
2312 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
2313
2314 // Save off the controller, so that we do not touch the request after it
2315 // is completed.
2316 SCIC_SDS_CONTROLLER_T * owning_controller = this_request->parent.owning_controller;
2317
2318 SCIC_LOG_TRACE((
2319 sci_base_object_get_logger(this_request),
2320 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2321 "scic_sds_stp_request_soft_reset_await_d2h_frame_handler(0x%x, 0x%x) enter\n",
2322 this_request, frame_index
2323 ));
2324
2325 status = scic_sds_unsolicited_frame_control_get_header(
2326 &(owning_controller->uf_control),
2327 frame_index,
2328 (void**) &frame_header
2329 );
2330
2331 if (status == SCI_SUCCESS)
2332 {
2333 switch (frame_header->fis_type)
2334 {
2335 case SATA_FIS_TYPE_REGD2H:
2336 scic_sds_unsolicited_frame_control_get_buffer(
2337 &(owning_controller->uf_control),
2338 frame_index,
2339 (void**) &frame_buffer
2340 );
2341
2342 scic_sds_controller_copy_sata_response(
2343 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer
2344 );
2345
2346 // The command has completed with error
2347 scic_sds_request_set_status(
2348 &this_request->parent,
2349 SCU_TASK_DONE_CHECK_RESPONSE,
2350 SCI_FAILURE_IO_RESPONSE_VALID
2351 );
2352 break;
2353
2354 default:
2355 SCIC_LOG_WARNING((
2356 sci_base_object_get_logger(this_request),
2357 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2358 "IO Request:0x%x Frame Id:%d protocol violation occurred\n",
2359 this_request, frame_index
2360 ));
2361
2362 scic_sds_request_set_status(
2363 &this_request->parent,
2364 SCU_TASK_DONE_UNEXP_FIS,
2365 SCI_FAILURE_PROTOCOL_VIOLATION
2366 );
2367 break;
2368 }
2369
2370 sci_base_state_machine_change_state(
2371 &this_request->parent.parent.state_machine,
2372 SCI_BASE_REQUEST_STATE_COMPLETED
2373 );
2374
2375 // Frame has been decoded return it to the controller
2376 scic_sds_controller_release_frame(
2377 owning_controller, frame_index
2378 );
2379 }
2380 else
2381 {
2382 SCIC_LOG_ERROR((
2383 sci_base_object_get_logger(this_request),
2384 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2385 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
2386 this_request, frame_index, status
2387 ));
2388 }
2389
2390 return status;
2391 }
2392
2393 // ---------------------------------------------------------------------------
2394
2395 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T
2396 scic_sds_stp_request_started_soft_reset_substate_handler_table
2397 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_MAX_SUBSTATES] =
2398 {
2399 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
2400 {
2401 {
2402 scic_sds_request_default_start_handler,
2403 scic_sds_request_started_state_abort_handler,
2404 scic_sds_request_default_complete_handler,
2405 scic_sds_request_default_destruct_handler
2406 },
2407 scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler,
2408 scic_sds_request_default_event_handler,
2409 scic_sds_request_default_frame_handler
2410 },
2411 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
2412 {
2413 {
2414 scic_sds_request_default_start_handler,
2415 scic_sds_request_started_state_abort_handler,
2416 scic_sds_request_default_complete_handler,
2417 scic_sds_request_default_destruct_handler
2418 },
2419 scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler,
2420 scic_sds_request_default_event_handler,
2421 scic_sds_request_default_frame_handler
2422 },
2423 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
2424 {
2425 {
2426 scic_sds_request_default_start_handler,
2427 scic_sds_request_started_state_abort_handler,
2428 scic_sds_request_default_complete_handler,
2429 scic_sds_request_default_destruct_handler
2430 },
2431 scic_sds_request_default_tc_completion_handler,
2432 scic_sds_request_default_event_handler,
2433 scic_sds_stp_request_soft_reset_await_d2h_frame_handler
2434 }
2435 };
2436
2437 static
2438 void scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter(
2439 SCI_BASE_OBJECT_T *object
2440 )
2441 {
2442 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2443
2444 SET_STATE_HANDLER(
2445 this_request,
2446 scic_sds_stp_request_started_soft_reset_substate_handler_table,
2447 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
2448 );
2449
2450 scic_sds_remote_device_set_working_request(
2451 this_request->target_device, this_request
2452 );
2453 }
2454
2455 static
2456 void scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter(
2457 SCI_BASE_OBJECT_T *object
2458 )
2459 {
2460 SCI_STATUS status;
2461 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2462 SATA_FIS_REG_H2D_T *h2d_fis;
2463 SCU_TASK_CONTEXT_T *task_context;
2464
2465 // Clear the SRST bit
2466 h2d_fis = scic_stp_io_request_get_h2d_reg_address(this_request);
2467 h2d_fis->control = 0;
2468
2469 // Clear the TC control bit
2470 task_context = scic_sds_controller_get_task_context_buffer(
2471 this_request->owning_controller, this_request->io_tag);
2472 task_context->control_frame = 0;
2473
2474 status = this_request->owning_controller->state_handlers->parent.continue_io_handler(
2475 &this_request->owning_controller->parent,
2476 &this_request->target_device->parent,
2477 &this_request->parent
2478 );
2479
2480 if (status == SCI_SUCCESS)
2481 {
2482 SET_STATE_HANDLER(
2483 this_request,
2484 scic_sds_stp_request_started_soft_reset_substate_handler_table,
2485 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
2486 );
2487 }
2488 }
2489
2490 static
2491 void scic_sds_stp_request_started_soft_reset_await_d2h_response_enter(
2492 SCI_BASE_OBJECT_T *object
2493 )
2494 {
2495 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2496
2497 SET_STATE_HANDLER(
2498 this_request,
2499 scic_sds_stp_request_started_soft_reset_substate_handler_table,
2500 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
2501 );
2502 }
2503
2504 // ---------------------------------------------------------------------------
2505
2506 SCI_BASE_STATE_T
2507 scic_sds_stp_request_started_soft_reset_substate_table
2508 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_MAX_SUBSTATES] =
2509 {
2510 {
2511 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE,
2512 scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter,
2513 NULL
2514 },
2515 {
2516 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE,
2517 scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter,
2518 NULL
2519 },
2520 {
2521 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE,
2522 scic_sds_stp_request_started_soft_reset_await_d2h_response_enter,
2523 NULL
2524 }
2525 };
2526
2527 // ---------------------------------------------------------------------------
2528
2529 SCI_STATUS scic_io_request_construct_basic_sata(
2530 SCI_IO_REQUEST_HANDLE_T scic_io_request
2531 )
2532 {
2533 SCI_STATUS status;
2534 SCIC_SDS_REQUEST_T * request = (SCIC_SDS_REQUEST_T *)scic_io_request;
2535
2536 SCIC_LOG_TRACE((
2537 sci_base_object_get_logger(scic_io_request),
2538 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2539 "scic_io_request_construct_basic_sata(0x%x) enter\n",
2540 scic_io_request
2541 ));
2542
2543 status = scic_sds_io_request_construct_sata(
2544 request,
2545 scic_cb_request_get_sat_protocol(request->user_request),
2546 scic_cb_io_request_get_transfer_length(request->user_request),
2547 scic_cb_io_request_get_data_direction(request->user_request),
2548 scic_cb_io_request_do_copy_rx_frames(request->user_request),
2549 TRUE
2550 );
2551
2552 return status;
2553 }
2554
2555 // ---------------------------------------------------------------------------
2556
2557 SCI_STATUS scic_io_request_construct_advanced_sata(
2558 SCI_IO_REQUEST_HANDLE_T scic_io_request,
2559 SCIC_IO_SATA_PARAMETERS_T * io_parameters
2560 )
2561 {
2562 SCI_STATUS status;
2563 SCIC_SDS_REQUEST_T * request = (SCIC_SDS_REQUEST_T *)scic_io_request;
2564
2565 SCIC_LOG_TRACE((
2566 sci_base_object_get_logger(scic_io_request),
2567 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2568 "scic_io_request_construct_basic_sata(0x%x) enter\n",
2569 scic_io_request
2570 ));
2571
2572 status = scic_sds_io_request_construct_sata(
2573 request,
2574 scic_cb_request_get_sat_protocol(request->user_request),
2575 scic_sds_request_get_sgl_element_pair(request, 0)->A.length,
2576 scic_cb_io_request_get_data_direction(request->user_request),
2577 scic_cb_io_request_do_copy_rx_frames(request->user_request),
2578 io_parameters->do_translate_sgl
2579 );
2580
2581 return status;
2582 }
2583
Cache object: 62394d093715f9ce675fb2e400ae39bd
|