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