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/**
59 * @file
60 *
61 * @brief This file contains the method implementations for the
62 *        SCIF_SAS_STP_IO_REQUEST object.  The contents will implement
63 *        SATA/STP specific functionality.
64 */
65
66#include <dev/isci/scil/scif_sas_stp_io_request.h>
67#include <dev/isci/scil/scif_sas_stp_remote_device.h>
68#include <dev/isci/scil/scif_sas_logger.h>
69#include <dev/isci/scil/scif_sas_controller.h>
70
71#include <dev/isci/scil/sci_status.h>
72#include <dev/isci/scil/scic_io_request.h>
73
74#include <dev/isci/scil/sati.h>
75#include <dev/isci/scil/sati_atapi.h>
76#include <dev/isci/scil/intel_sat.h>
77#include <dev/isci/scil/sati_util.h>
78#include <dev/isci/scil/sati_callbacks.h>
79
80//******************************************************************************
81// P R I V A T E   M E T H O D S
82//******************************************************************************
83
84/**
85 * @brief This method provides SATA/STP CONSTRUCTED state specific handling
86 *        for when the user attempts to start the supplied IO request.  It
87 *        will allocate NCQ tags if necessary.
88 *
89 * @param[in] io_request This parameter specifies the IO request object
90 *            to be started.
91 *
92 * @return This method returns a value indicating if the IO request was
93 *         successfully started or not.
94 * @retval SCI_SUCCESS This return value indicates successful starting
95 *         of the IO request.
96 */
97static
98SCI_STATUS scif_sas_stp_io_request_constructed_start_handler(
99   SCI_BASE_REQUEST_T * io_request
100)
101{
102   SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) io_request;
103
104   SCIF_LOG_TRACE((
105      sci_base_object_get_logger(io_request),
106      SCIF_LOG_OBJECT_IO_REQUEST,
107      "scif_sas_stp_io_request_constructed_start_handler(0x%x) enter\n",
108      io_request
109   ));
110
111   if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_FPDMA)
112   {
113      SATA_FIS_REG_H2D_T * fis;
114
115      // For NCQ, we need to attempt to allocate an available tag.
116      fw_io->parent.stp.ncq_tag = scif_sas_stp_remote_device_allocate_ncq_tag(
117                                     fw_io->parent.device
118                                  );
119
120      if (fw_io->parent.stp.ncq_tag == SCIF_SAS_INVALID_NCQ_TAG)
121         return SCI_FAILURE_NO_NCQ_TAG_AVAILABLE;
122
123      // Set the NCQ tag in the host to device register FIS (upper 5 bits
124      // of the 8-bit sector count register).
125      fis = scic_stp_io_request_get_h2d_reg_address(fw_io->parent.core_object);
126      fis->sector_count = (fw_io->parent.stp.ncq_tag << 3);
127
128      // The Core also requires that we inform it separately regarding the
129      // NCQ tag for this IO.
130      scic_stp_io_request_set_ncq_tag(
131         fw_io->parent.core_object, fw_io->parent.stp.ncq_tag
132      );
133   }
134
135   return SCI_SUCCESS;
136}
137
138/**
139 * @brief This method provides SATA/STP CONSTRUCTED state specific handling
140 *        for when the user attempts to complete the supplied IO request.
141 *        This method will be invoked in the event the call to start the
142 *        core IO request fails for some reason.  In this situation, the
143 *        NCQ tag will be freed.
144 *
145 * @param[in] io_request This parameter specifies the IO request object
146 *            to be started.
147 *
148 * @return This method returns a value indicating if the IO request was
149 *         successfully started or not.
150 * @retval SCI_SUCCESS This return value indicates successful starting
151 *         of the IO request.
152 */
153static
154SCI_STATUS scif_sas_stp_io_request_constructed_complete_handler(
155   SCI_BASE_REQUEST_T * io_request
156)
157{
158   SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) io_request;
159
160   SCIF_LOG_TRACE((
161      sci_base_object_get_logger(io_request),
162      SCIF_LOG_OBJECT_IO_REQUEST,
163      "scif_sas_stp_io_request_constructed_complete_handler(0x%x) enter\n",
164      io_request
165   ));
166
167   if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_FPDMA)
168   {
169      // For NCQ, we need to return the tag back to the free pool.
170      if (fw_io->parent.stp.ncq_tag != SCIF_SAS_INVALID_NCQ_TAG)
171         scif_sas_stp_remote_device_free_ncq_tag(
172            fw_io->parent.device, fw_io->parent.stp.ncq_tag
173         );
174   }
175
176   sati_sequence_terminate(&fw_io->parent.stp.sequence, fw_io, fw_io);
177
178   return SCI_SUCCESS;
179}
180/**
181 * @brief This method provides SATA/STP STARTED state specific handling for
182 *        when the user attempts to complete the supplied IO request.
183 *        It will perform data/response translation and free NCQ tags
184 *        if necessary.
185 *
186 * @param[in] io_request This parameter specifies the IO request object
187 *            to be started.
188 *
189 * @return This method returns a value indicating if the IO request was
190 *         successfully completed or not.
191 */
192static
193SCI_STATUS scif_sas_stp_core_cb_io_request_complete_handler(
194   SCIF_SAS_CONTROLLER_T    * fw_controller,
195   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
196   SCIF_SAS_REQUEST_T       * fw_request,
197   SCI_STATUS               * completion_status
198)
199{
200   SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) fw_request;
201
202   SCIF_LOG_TRACE((
203      sci_base_object_get_logger(fw_controller),
204      SCIF_LOG_OBJECT_IO_REQUEST,
205      "scif_sas_stp_core_cb_io_request_complete_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
206      fw_controller, fw_device, fw_request, *completion_status
207   ));
208
209   if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_FPDMA)
210      scif_sas_stp_remote_device_free_ncq_tag(
211         fw_request->device, fw_io->parent.stp.ncq_tag
212      );
213
214   // Translating the response is only necessary if:
215   // - some sort of error occurred resulting in having the error bit
216   //   set in the ATA status register and values to decode in the
217   //   ATA error register.
218   // - the command returns information in the register FIS itself,
219   //   which requires translation.
220   // - the request completed ok but the sequence requires a callback
221   //   to possibly continue the translation
222   if ((*completion_status == SCI_FAILURE_IO_RESPONSE_VALID) ||
223       ((sati_cb_do_translate_response(fw_request)) &&
224        (*completion_status != SCI_FAILURE_IO_TERMINATED)))
225   {
226      SATI_STATUS sati_status = sati_translate_command_response(
227                                   &fw_io->parent.stp.sequence, fw_io, fw_io
228                                );
229      if (sati_status == SATI_COMPLETE)
230         *completion_status = SCI_SUCCESS;
231      else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA)
232         *completion_status = SCI_FAILURE_IO_RESPONSE_VALID;
233      else if (sati_status == SATI_SEQUENCE_INCOMPLETE)
234      {
235         // The translation indicates that additional SATA requests are
236         // necessary to finish the original SCSI request.  As a result,
237         // do not complete the IO and begin the next stage of the
238         // translation.
239         return SCI_WARNING_SEQUENCE_INCOMPLETE;
240      }
241      else if (sati_status == SATI_COMPLETE_IO_DONE_EARLY)
242         *completion_status = SCI_SUCCESS_IO_DONE_EARLY;
243      else
244      {
245         // Something unexpected occurred during translation.  Fail the
246         // IO request to the user.
247         *completion_status = SCI_FAILURE;
248      }
249   }
250   else if (*completion_status != SCI_SUCCESS)
251   {
252      SCIF_LOG_INFO((
253         sci_base_object_get_logger(fw_controller),
254         SCIF_LOG_OBJECT_IO_REQUEST,
255         "Sequence Terminated(0x%x, 0x%x, 0x%x)\n",
256         fw_controller, fw_device, fw_request
257      ));
258
259      sati_sequence_terminate(&fw_io->parent.stp.sequence, fw_io, fw_io);
260   }
261
262   return SCI_SUCCESS;
263}
264
265#if !defined(DISABLE_ATAPI)
266/**
267 * @brief This method provides STP PACKET io request STARTED state specific handling for
268 *        when the user attempts to complete the supplied IO request.
269 *        It will perform data/response translation.
270 *
271 * @param[in] io_request This parameter specifies the IO request object
272 *            to be started.
273 *
274 * @return This method returns a value indicating if the IO request was
275 *         successfully completed or not.
276 */
277static
278SCI_STATUS scif_sas_stp_core_cb_packet_io_request_complete_handler(
279   SCIF_SAS_CONTROLLER_T    * fw_controller,
280   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
281   SCIF_SAS_REQUEST_T       * fw_request,
282   SCI_STATUS               * completion_status
283)
284{
285   SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) fw_request;
286   SATI_STATUS sati_status;
287
288   SCIF_LOG_TRACE((
289      sci_base_object_get_logger(fw_controller),
290      SCIF_LOG_OBJECT_IO_REQUEST,
291      "scif_sas_stp_packet_core_cb_io_request_complete_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
292      fw_controller, fw_device, fw_request, *completion_status
293   ));
294
295   if (*completion_status == SCI_FAILURE_IO_RESPONSE_VALID)
296   {
297      sati_status = sati_atapi_translate_command_response(
298                       &fw_io->parent.stp.sequence, fw_io, fw_io
299                    );
300
301      if (sati_status == SATI_COMPLETE)
302         *completion_status = SCI_SUCCESS;
303      else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA)
304         *completion_status = SCI_FAILURE_IO_RESPONSE_VALID;
305      else if (sati_status == SATI_SEQUENCE_INCOMPLETE)
306      {
307         // The translation indicates that additional REQUEST SENSE command is
308         // necessary to finish the original SCSI request.  As a result,
309         // do not complete the IO and begin the next stage of the IO.
310         return SCI_WARNING_SEQUENCE_INCOMPLETE;
311      }
312      else
313      {
314         // Something unexpected occurred during translation.  Fail the
315         // IO request to the user.
316         *completion_status = SCI_FAILURE;
317      }
318   }
319   else if (*completion_status == SCI_SUCCESS &&
320        fw_request->stp.sequence.state == SATI_SEQUENCE_STATE_INCOMPLETE)
321   {
322      //The internal Request Sense command is completed successfully.
323      sati_atapi_translate_request_sense_response(
324         &fw_io->parent.stp.sequence, fw_io, fw_io
325      );
326
327      *completion_status = SCI_FAILURE_IO_RESPONSE_VALID;
328   }
329
330   return SCI_SUCCESS;
331}
332#endif // !defined(DISABLE_ATAPI)
333
334//******************************************************************************
335// P R O T E C T E D   M E T H O D S
336//******************************************************************************
337
338/**
339 * @brief This method will construct the SATA/STP specific IO request
340 *        object utilizing the SATI.
341 *
342 * @pre The scif_sas_request_construct() method should be invoked before
343 *      calling this method.
344 *
345 * @param[in,out] stp_io_request This parameter specifies the stp_io_request
346 *                to be constructed.
347 *
348 * @return Indicate if the construction was successful.
349 * @return SCI_FAILURE_NO_NCQ_TAG_AVAILABLE
350 * @return SCI_SUCCESS_IO_COMPLETE_BEFORE_START
351 * @return SCI_FAILURE_IO_RESPONSE_VALID
352 * @return SCI_FAILURE This return value indicates a change in the translator
353 *         where a new return code has been given, but is not yet understood
354 *         by this routine.
355 */
356SCI_STATUS scif_sas_stp_io_request_construct(
357   SCIF_SAS_IO_REQUEST_T * fw_io
358)
359{
360   SATI_STATUS                sati_status;
361   SCI_STATUS                 sci_status = SCI_FAILURE;
362   SCIF_SAS_REMOTE_DEVICE_T * fw_device  = fw_io->parent.device;
363
364   SCIF_LOG_TRACE((
365      sci_base_object_get_logger(fw_io),
366      SCIF_LOG_OBJECT_IO_REQUEST,
367      "scif_sas_stp_io_request_construct(0x%x) enter\n",
368      fw_io
369   ));
370
371   // The translator will indirectly invoke core methods to set the fields
372   // of the ATA register FIS inside of this method.
373   sati_status = sati_translate_command(
374                    &fw_io->parent.stp.sequence,
375                    &fw_device->protocol_device.stp_device.sati_device,
376                    fw_io,
377                    fw_io
378                 );
379
380   if (sati_status == SATI_SUCCESS)
381   {
382      // Allow the core to finish construction of the IO request.
383      sci_status = scic_io_request_construct_basic_sata(fw_io->parent.core_object);
384      fw_io->parent.state_handlers = &stp_io_request_constructed_handlers;
385      fw_io->parent.protocol_complete_handler
386         = scif_sas_stp_core_cb_io_request_complete_handler;
387   }
388   else if (sati_status == SATI_SUCCESS_SGL_TRANSLATED)
389   {
390      SCIC_IO_SATA_PARAMETERS_T parms;
391      parms.do_translate_sgl = FALSE;
392
393      // The translation actually already caused translation of the
394      // scatter gather list.  So, call into the core through an API
395      // that will not attempt to translate the SGL.
396      scic_io_request_construct_advanced_sata(
397                      fw_io->parent.core_object, &parms
398                   );
399      fw_io->parent.state_handlers = &stp_io_request_constructed_handlers;
400      fw_io->parent.protocol_complete_handler
401         = scif_sas_stp_core_cb_io_request_complete_handler;
402      // Done with translation
403      sci_status = SCI_SUCCESS;
404   }
405   else if (sati_status == SATI_COMPLETE)
406      sci_status = SCI_SUCCESS_IO_COMPLETE_BEFORE_START;
407   else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA)
408      sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
409   else
410   {
411      SCIF_LOG_ERROR((
412         sci_base_object_get_logger(fw_io),
413         SCIF_LOG_OBJECT_IO_REQUEST,
414         "Unexpected SAT translation failure 0x%x\n",
415         fw_io
416      ));
417   }
418
419   return sci_status;
420}
421
422
423#if !defined(DISABLE_ATAPI)
424/**
425 * @brief This method will construct the STP PACKET protocol specific IO
426 *        request object.
427 *
428 * @pre The scif_sas_request_construct() method should be invoked before
429 *      calling this method.
430 *
431 * @param[in,out] fw_io This parameter specifies the stp packet io request
432 *                to be constructed.
433 *
434 * @return Indicate if the construction was successful.
435 * @return SCI_SUCCESS_IO_COMPLETE_BEFORE_START
436 * @return SCI_FAILURE_IO_RESPONSE_VALID
437 * @return SCI_FAILURE This return value indicates a change in the translator
438 *         where a new return code has been given, but is not yet understood
439 *         by this routine.
440 */
441SCI_STATUS scif_sas_stp_packet_io_request_construct(
442   SCIF_SAS_IO_REQUEST_T * fw_io
443)
444{
445   SATI_STATUS                sati_status;
446   SCI_STATUS                 sci_status = SCI_FAILURE;
447   SCIF_SAS_REMOTE_DEVICE_T * fw_device  = fw_io->parent.device;
448
449   SCIF_LOG_TRACE((
450      sci_base_object_get_logger(fw_io),
451      SCIF_LOG_OBJECT_IO_REQUEST,
452      "scif_sas_stp_packet_io_request_construct(0x%x) enter\n",
453      fw_io
454   ));
455
456   sati_status = sati_atapi_translate_command(
457                    &fw_io->parent.stp.sequence,
458                    &fw_device->protocol_device.stp_device.sati_device,
459                    fw_io,
460                    fw_io
461                 );
462
463   if (sati_status == SATI_SUCCESS)
464   {
465      // Allow the core to finish construction of the IO request.
466      sci_status = scic_io_request_construct_basic_sata(fw_io->parent.core_object);
467
468      fw_io->parent.protocol_complete_handler
469         = scif_sas_stp_core_cb_packet_io_request_complete_handler;
470   }
471   else if (sati_status == SATI_COMPLETE)
472      sci_status = SCI_SUCCESS_IO_COMPLETE_BEFORE_START;
473   else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA)
474      sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
475   else
476   {
477      SCIF_LOG_ERROR((
478         sci_base_object_get_logger(fw_io),
479         SCIF_LOG_OBJECT_IO_REQUEST,
480         "Unexpected SAT ATAPI translation failure 0x%x\n",
481         fw_io
482      ));
483   }
484
485   return sci_status;
486}
487#endif
488
489
490#if !defined(DISABLE_ATAPI)
491/**
492 * @brief This method will get the number of bytes transferred in an packet IO.
493 *
494 * @param[in] fw_io This parameter specifies the stp packet io request whose
495 *                     actual transferred length is to be retrieved.
496 *
497 * @return Actual length of transferred data.
498 */
499U32 scif_sas_stp_packet_io_request_get_number_of_bytes_transferred(
500   SCIF_SAS_IO_REQUEST_T * fw_io
501)
502{
503   SCI_IO_REQUEST_HANDLE_T scic_io = scif_io_request_get_scic_handle(fw_io);
504   SCI_IO_STATUS io_status = scic_request_get_sci_status (scic_io);
505   U32 actual_data_length;
506
507   if (io_status == SCI_IO_FAILURE_RESPONSE_VALID)
508       actual_data_length = 0;
509   else if (io_status == SCI_IO_SUCCESS_IO_DONE_EARLY)
510   {
511      actual_data_length = sati_atapi_translate_number_of_bytes_transferred(
512         &fw_io->parent.stp.sequence, fw_io, fw_io);
513
514      if (actual_data_length == 0)
515         actual_data_length =
516            scic_io_request_get_number_of_bytes_transferred(scic_io);
517   }
518   else
519      actual_data_length =
520         scic_io_request_get_number_of_bytes_transferred(scic_io);
521
522   return actual_data_length;
523}
524#endif
525
526
527//******************************************************************************
528// P U B L I C   M E T H O D S
529//******************************************************************************
530
531BOOL scic_cb_io_request_do_copy_rx_frames(
532   void * scic_user_io_request
533)
534{
535   SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) scic_user_io_request;
536
537   SCIF_LOG_TRACE((
538      sci_base_object_get_logger(fw_io),
539      SCIF_LOG_OBJECT_IO_REQUEST,
540      "scic_cb_io_request_do_copy_rx_frames(0x%x) enter\n",
541      fw_io
542   ));
543
544   // If the translation was a PIO DATA IN (i.e. read) and the request
545   // was actually a READ payload operation, then copy the data, since
546   // there will be SGL space allocated for the transfer.
547   if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_PIO_DATA_IN)
548   {
549      if (
550            (fw_io->parent.stp.sequence.type ==  SATI_SEQUENCE_ATA_PASSTHROUGH_12)
551         || (fw_io->parent.stp.sequence.type ==  SATI_SEQUENCE_ATA_PASSTHROUGH_16)
552         || (
553               (fw_io->parent.stp.sequence.type >= SATI_SEQUENCE_TYPE_READ_MIN)
554            && (fw_io->parent.stp.sequence.type <= SATI_SEQUENCE_TYPE_READ_MAX)
555            )
556         )
557      {
558           SCIF_LOG_TRACE((
559                 sci_base_object_get_logger(fw_io),
560                 SCIF_LOG_OBJECT_IO_REQUEST,
561                 "scic_cb_io_request_do_copy_rx_frames(0x%x) TRUE\n",
562                 fw_io
563              ));
564           return TRUE;
565      }
566   }
567
568   // For all other requests we leave the data in the core buffers.
569   // This allows the translation to translate without having to have
570   // separate space allocated into which to copy the data.
571   return FALSE;
572}
573
574// ---------------------------------------------------------------------------
575
576U8 scic_cb_request_get_sat_protocol(
577   void * scic_user_io_request
578)
579{
580   SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) scic_user_io_request;
581
582   return fw_io->parent.stp.sequence.protocol;
583}
584
585U8 *scic_cb_io_request_get_virtual_address_from_sgl(
586   void * scic_user_io_request,
587   U32    byte_offset
588)
589{
590   SCIF_SAS_REQUEST_T *fw_request =
591      (SCIF_SAS_REQUEST_T *) sci_object_get_association(scic_user_io_request);
592
593   return scif_cb_io_request_get_virtual_address_from_sgl(
594             sci_object_get_association(fw_request),
595             byte_offset
596          );
597}
598
599#ifdef ENABLE_OSSL_COPY_BUFFER
600void scic_cb_io_request_copy_buffer(
601   void * scic_user_io_request,
602   U8    *source_addr,
603   U32   offset,
604   U32   length
605)
606{
607   SCIF_SAS_REQUEST_T *fw_request =
608      (SCIF_SAS_REQUEST_T *)sci_object_get_association(scic_user_io_request);
609
610   return scif_cb_io_request_copy_buffer(
611             sci_object_get_association(fw_request),
612             source_addr,
613             offset,
614             length
615          );
616}
617#endif
618// ---------------------------------------------------------------------------
619
620SCI_BASE_REQUEST_STATE_HANDLER_T stp_io_request_constructed_handlers =
621{
622   scif_sas_stp_io_request_constructed_start_handler,
623   scif_sas_io_request_constructed_abort_handler,
624   scif_sas_stp_io_request_constructed_complete_handler,
625   scif_sas_io_request_default_destruct_handler
626};
627
628