16f231ddaSDan Williams /* 26f231ddaSDan Williams * This file is provided under a dual BSD/GPLv2 license. When using or 36f231ddaSDan Williams * redistributing this file, you may do so under either license. 46f231ddaSDan Williams * 56f231ddaSDan Williams * GPL LICENSE SUMMARY 66f231ddaSDan Williams * 76f231ddaSDan Williams * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 86f231ddaSDan Williams * 96f231ddaSDan Williams * This program is free software; you can redistribute it and/or modify 106f231ddaSDan Williams * it under the terms of version 2 of the GNU General Public License as 116f231ddaSDan Williams * published by the Free Software Foundation. 126f231ddaSDan Williams * 136f231ddaSDan Williams * This program is distributed in the hope that it will be useful, but 146f231ddaSDan Williams * WITHOUT ANY WARRANTY; without even the implied warranty of 156f231ddaSDan Williams * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 166f231ddaSDan Williams * General Public License for more details. 176f231ddaSDan Williams * 186f231ddaSDan Williams * You should have received a copy of the GNU General Public License 196f231ddaSDan Williams * along with this program; if not, write to the Free Software 206f231ddaSDan Williams * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 216f231ddaSDan Williams * The full GNU General Public License is included in this distribution 226f231ddaSDan Williams * in the file called LICENSE.GPL. 236f231ddaSDan Williams * 246f231ddaSDan Williams * BSD LICENSE 256f231ddaSDan Williams * 266f231ddaSDan Williams * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 276f231ddaSDan Williams * All rights reserved. 286f231ddaSDan Williams * 296f231ddaSDan Williams * Redistribution and use in source and binary forms, with or without 306f231ddaSDan Williams * modification, are permitted provided that the following conditions 316f231ddaSDan Williams * are met: 326f231ddaSDan Williams * 336f231ddaSDan Williams * * Redistributions of source code must retain the above copyright 346f231ddaSDan Williams * notice, this list of conditions and the following disclaimer. 356f231ddaSDan Williams * * Redistributions in binary form must reproduce the above copyright 366f231ddaSDan Williams * notice, this list of conditions and the following disclaimer in 376f231ddaSDan Williams * the documentation and/or other materials provided with the 386f231ddaSDan Williams * distribution. 396f231ddaSDan Williams * * Neither the name of Intel Corporation nor the names of its 406f231ddaSDan Williams * contributors may be used to endorse or promote products derived 416f231ddaSDan Williams * from this software without specific prior written permission. 426f231ddaSDan Williams * 436f231ddaSDan Williams * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 446f231ddaSDan Williams * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 456f231ddaSDan Williams * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 466f231ddaSDan Williams * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 476f231ddaSDan Williams * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 486f231ddaSDan Williams * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 496f231ddaSDan Williams * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 506f231ddaSDan Williams * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 516f231ddaSDan Williams * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 526f231ddaSDan Williams * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 536f231ddaSDan Williams * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 546f231ddaSDan Williams */ 556f231ddaSDan Williams 560d84366fSDan Williams #ifndef _ISCI_REQUEST_H_ 576f231ddaSDan Williams #define _ISCI_REQUEST_H_ 586f231ddaSDan Williams 596f231ddaSDan Williams #include "isci.h" 60ce2b3261SDan Williams #include "host.h" 61f1f52e75SDan Williams #include "scu_task_context.h" 626f231ddaSDan Williams 636f231ddaSDan Williams /** 646f231ddaSDan Williams * struct isci_request_status - This enum defines the possible states of an I/O 656f231ddaSDan Williams * request. 666f231ddaSDan Williams * 676f231ddaSDan Williams * 686f231ddaSDan Williams */ 696f231ddaSDan Williams enum isci_request_status { 706f231ddaSDan Williams unallocated = 0x00, 716f231ddaSDan Williams allocated = 0x01, 726f231ddaSDan Williams started = 0x02, 736f231ddaSDan Williams completed = 0x03, 746f231ddaSDan Williams aborting = 0x04, 756f231ddaSDan Williams aborted = 0x05, 764dc043c4SJeff Skirvin terminating = 0x06, 774dc043c4SJeff Skirvin dead = 0x07 786f231ddaSDan Williams }; 796f231ddaSDan Williams 806f231ddaSDan Williams enum task_type { 816f231ddaSDan Williams io_task = 0, 826f231ddaSDan Williams tmf_task = 1 836f231ddaSDan Williams }; 846f231ddaSDan Williams 85f1f52e75SDan Williams enum sci_request_protocol { 86f1f52e75SDan Williams SCIC_NO_PROTOCOL, 87f1f52e75SDan Williams SCIC_SMP_PROTOCOL, 88f1f52e75SDan Williams SCIC_SSP_PROTOCOL, 89f1f52e75SDan Williams SCIC_STP_PROTOCOL 90c72086e3SDan Williams }; /* XXX remove me, use sas_task.{dev|task_proto} instead */; 91f1f52e75SDan Williams 92*5dec6f4eSDan Williams struct scic_sds_stp_request { 93*5dec6f4eSDan Williams union { 94*5dec6f4eSDan Williams u32 ncq; 95*5dec6f4eSDan Williams 96*5dec6f4eSDan Williams u32 udma; 97*5dec6f4eSDan Williams 98*5dec6f4eSDan Williams struct scic_sds_stp_pio_request { 99*5dec6f4eSDan Williams /** 100*5dec6f4eSDan Williams * Total transfer for the entire PIO request recorded at request constuction 101*5dec6f4eSDan Williams * time. 102*5dec6f4eSDan Williams * 103*5dec6f4eSDan Williams * @todo Should we just decrement this value for each byte of data transitted 104*5dec6f4eSDan Williams * or received to elemenate the current_transfer_bytes field? 105*5dec6f4eSDan Williams */ 106*5dec6f4eSDan Williams u32 total_transfer_bytes; 107*5dec6f4eSDan Williams 108*5dec6f4eSDan Williams /** 109*5dec6f4eSDan Williams * Total number of bytes received/transmitted in data frames since the start 110*5dec6f4eSDan Williams * of the IO request. At the end of the IO request this should equal the 111*5dec6f4eSDan Williams * total_transfer_bytes. 112*5dec6f4eSDan Williams */ 113*5dec6f4eSDan Williams u32 current_transfer_bytes; 114*5dec6f4eSDan Williams 115*5dec6f4eSDan Williams /** 116*5dec6f4eSDan Williams * The number of bytes requested in the in the PIO setup. 117*5dec6f4eSDan Williams */ 118*5dec6f4eSDan Williams u32 pio_transfer_bytes; 119*5dec6f4eSDan Williams 120*5dec6f4eSDan Williams /** 121*5dec6f4eSDan Williams * PIO Setup ending status value to tell us if we need to wait for another FIS 122*5dec6f4eSDan Williams * or if the transfer is complete. On the receipt of a D2H FIS this will be 123*5dec6f4eSDan Williams * the status field of that FIS. 124*5dec6f4eSDan Williams */ 125*5dec6f4eSDan Williams u8 ending_status; 126*5dec6f4eSDan Williams 127*5dec6f4eSDan Williams /** 128*5dec6f4eSDan Williams * On receipt of a D2H FIS this will be the ending error field if the 129*5dec6f4eSDan Williams * ending_status has the SATA_STATUS_ERR bit set. 130*5dec6f4eSDan Williams */ 131*5dec6f4eSDan Williams u8 ending_error; 132*5dec6f4eSDan Williams 133*5dec6f4eSDan Williams struct scic_sds_request_pio_sgl { 134*5dec6f4eSDan Williams struct scu_sgl_element_pair *sgl_pair; 135*5dec6f4eSDan Williams u8 sgl_set; 136*5dec6f4eSDan Williams u32 sgl_offset; 137*5dec6f4eSDan Williams } request_current; 138*5dec6f4eSDan Williams } pio; 139*5dec6f4eSDan Williams 140*5dec6f4eSDan Williams struct { 141*5dec6f4eSDan Williams /** 142*5dec6f4eSDan Williams * The number of bytes requested in the PIO setup before CDB data frame. 143*5dec6f4eSDan Williams */ 144*5dec6f4eSDan Williams u32 device_preferred_cdb_length; 145*5dec6f4eSDan Williams } packet; 146*5dec6f4eSDan Williams } type; 147*5dec6f4eSDan Williams }; 148*5dec6f4eSDan Williams 149f1f52e75SDan Williams struct scic_sds_request { 150f1f52e75SDan Williams /** 151f1f52e75SDan Williams * This field contains the information for the base request state machine. 152f1f52e75SDan Williams */ 153f1f52e75SDan Williams struct sci_base_state_machine state_machine; 154f1f52e75SDan Williams 155f1f52e75SDan Williams /** 156f1f52e75SDan Williams * This field simply points to the controller to which this IO request 157f1f52e75SDan Williams * is associated. 158f1f52e75SDan Williams */ 159f1f52e75SDan Williams struct scic_sds_controller *owning_controller; 160f1f52e75SDan Williams 161f1f52e75SDan Williams /** 162f1f52e75SDan Williams * This field simply points to the remote device to which this IO request 163f1f52e75SDan Williams * is associated. 164f1f52e75SDan Williams */ 165f1f52e75SDan Williams struct scic_sds_remote_device *target_device; 166f1f52e75SDan Williams 167f1f52e75SDan Williams /** 168f1f52e75SDan Williams * This field is utilized to determine if the SCI user is managing 169f1f52e75SDan Williams * the IO tag for this request or if the core is managing it. 170f1f52e75SDan Williams */ 171f1f52e75SDan Williams bool was_tag_assigned_by_user; 172f1f52e75SDan Williams 173f1f52e75SDan Williams /** 174f1f52e75SDan Williams * This field indicates the IO tag for this request. The IO tag is 175f1f52e75SDan Williams * comprised of the task_index and a sequence count. The sequence count 176f1f52e75SDan Williams * is utilized to help identify tasks from one life to another. 177f1f52e75SDan Williams */ 178f1f52e75SDan Williams u16 io_tag; 179f1f52e75SDan Williams 180f1f52e75SDan Williams /** 181f1f52e75SDan Williams * This field specifies the protocol being utilized for this 182f1f52e75SDan Williams * IO request. 183f1f52e75SDan Williams */ 184f1f52e75SDan Williams enum sci_request_protocol protocol; 185f1f52e75SDan Williams 186f1f52e75SDan Williams /** 187f1f52e75SDan Williams * This field indicates the completion status taken from the SCUs 188f1f52e75SDan Williams * completion code. It indicates the completion result for the SCU hardware. 189f1f52e75SDan Williams */ 190f1f52e75SDan Williams u32 scu_status; 191f1f52e75SDan Williams 192f1f52e75SDan Williams /** 193f1f52e75SDan Williams * This field indicates the completion status returned to the SCI user. It 194f1f52e75SDan Williams * indicates the users view of the io request completion. 195f1f52e75SDan Williams */ 196f1f52e75SDan Williams u32 sci_status; 197f1f52e75SDan Williams 198f1f52e75SDan Williams /** 199f1f52e75SDan Williams * This field contains the value to be utilized when posting (e.g. Post_TC, 200f1f52e75SDan Williams * Post_TC_Abort) this request to the silicon. 201f1f52e75SDan Williams */ 202f1f52e75SDan Williams u32 post_context; 203f1f52e75SDan Williams 204f1f52e75SDan Williams struct scu_task_context *task_context_buffer; 205f1f52e75SDan Williams struct scu_task_context tc ____cacheline_aligned; 206f1f52e75SDan Williams 207f1f52e75SDan Williams /* could be larger with sg chaining */ 208f1f52e75SDan Williams #define SCU_SGL_SIZE ((SCU_IO_REQUEST_SGE_COUNT + 1) / 2) 209f1f52e75SDan Williams struct scu_sgl_element_pair sg_table[SCU_SGL_SIZE] __attribute__ ((aligned(32))); 210f1f52e75SDan Williams 211f1f52e75SDan Williams /** 212f1f52e75SDan Williams * This field indicates if this request is a task management request or 213f1f52e75SDan Williams * normal IO request. 214f1f52e75SDan Williams */ 215f1f52e75SDan Williams bool is_task_management_request; 216f1f52e75SDan Williams 217f1f52e75SDan Williams /** 218f1f52e75SDan Williams * This field is a pointer to the stored rx frame data. It is used in STP 219f1f52e75SDan Williams * internal requests and SMP response frames. If this field is non-NULL the 220f1f52e75SDan Williams * saved frame must be released on IO request completion. 221f1f52e75SDan Williams * 222f1f52e75SDan Williams * @todo In the future do we want to keep a list of RX frame buffers? 223f1f52e75SDan Williams */ 224f1f52e75SDan Williams u32 saved_rx_frame_index; 225f1f52e75SDan Williams 226f1f52e75SDan Williams /** 227f1f52e75SDan Williams * This field specifies the current state handlers in place for this 228f1f52e75SDan Williams * IO Request object. This field is updated each time the request 229f1f52e75SDan Williams * changes state. 230f1f52e75SDan Williams */ 231f1f52e75SDan Williams const struct scic_sds_io_request_state_handler *state_handlers; 232f1f52e75SDan Williams 233f1f52e75SDan Williams /** 234f1f52e75SDan Williams * This field in the recorded device sequence for the io request. This is 235f1f52e75SDan Williams * recorded during the build operation and is compared in the start 236f1f52e75SDan Williams * operation. If the sequence is different then there was a change of 237f1f52e75SDan Williams * devices from the build to start operations. 238f1f52e75SDan Williams */ 239f1f52e75SDan Williams u8 device_sequence; 240f1f52e75SDan Williams 241f1f52e75SDan Williams union { 242f1f52e75SDan Williams struct { 243f1f52e75SDan Williams union { 244f1f52e75SDan Williams struct ssp_cmd_iu cmd; 245f1f52e75SDan Williams struct ssp_task_iu tmf; 246f1f52e75SDan Williams }; 247f1f52e75SDan Williams union { 248f1f52e75SDan Williams struct ssp_response_iu rsp; 249f1f52e75SDan Williams u8 rsp_buf[SSP_RESP_IU_MAX_SIZE]; 250f1f52e75SDan Williams }; 251f1f52e75SDan Williams } ssp; 252f1f52e75SDan Williams 253f1f52e75SDan Williams struct { 254f1f52e75SDan Williams struct smp_req cmd; 255f1f52e75SDan Williams struct smp_resp rsp; 256f1f52e75SDan Williams } smp; 257f1f52e75SDan Williams 258f1f52e75SDan Williams struct { 259f1f52e75SDan Williams struct scic_sds_stp_request req; 260f1f52e75SDan Williams struct host_to_dev_fis cmd; 261f1f52e75SDan Williams struct dev_to_host_fis rsp; 262f1f52e75SDan Williams } stp; 263f1f52e75SDan Williams }; 264f1f52e75SDan Williams 265f1f52e75SDan Williams }; 266f1f52e75SDan Williams 267f1f52e75SDan Williams static inline struct scic_sds_request *to_sci_req(struct scic_sds_stp_request *stp_req) 268f1f52e75SDan Williams { 269f1f52e75SDan Williams struct scic_sds_request *sci_req; 270f1f52e75SDan Williams 271f1f52e75SDan Williams sci_req = container_of(stp_req, typeof(*sci_req), stp.req); 272f1f52e75SDan Williams return sci_req; 273f1f52e75SDan Williams } 274f1f52e75SDan Williams 2756f231ddaSDan Williams struct isci_request { 2766f231ddaSDan Williams enum isci_request_status status; 2776f231ddaSDan Williams enum task_type ttype; 2786f231ddaSDan Williams unsigned short io_tag; 2796f231ddaSDan Williams bool complete_in_target; 28067ea838dSDan Williams bool terminated; 2816f231ddaSDan Williams 2826f231ddaSDan Williams union ttype_ptr_union { 2836f231ddaSDan Williams struct sas_task *io_task_ptr; /* When ttype==io_task */ 2846f231ddaSDan Williams struct isci_tmf *tmf_task_ptr; /* When ttype==tmf_task */ 2856f231ddaSDan Williams } ttype_ptr; 2866f231ddaSDan Williams struct isci_host *isci_host; 2876f231ddaSDan Williams struct isci_remote_device *isci_device; 2886f231ddaSDan Williams /* For use in the requests_to_{complete|abort} lists: */ 2896f231ddaSDan Williams struct list_head completed_node; 2906f231ddaSDan Williams /* For use in the reqs_in_process list: */ 2916f231ddaSDan Williams struct list_head dev_node; 2926f231ddaSDan Williams spinlock_t state_lock; 2936f231ddaSDan Williams dma_addr_t request_daddr; 2946f231ddaSDan Williams dma_addr_t zero_scatter_daddr; 2956f231ddaSDan Williams 2966f231ddaSDan Williams unsigned int num_sg_entries; /* returned by pci_alloc_sg */ 2976f231ddaSDan Williams 2986f231ddaSDan Williams /** Note: "io_request_completion" is completed in two different ways 2996f231ddaSDan Williams * depending on whether this is a TMF or regular request. 3006f231ddaSDan Williams * - TMF requests are completed in the thread that started them; 3016f231ddaSDan Williams * - regular requests are completed in the request completion callback 3026f231ddaSDan Williams * function. 3036f231ddaSDan Williams * This difference in operation allows the aborter of a TMF request 3046f231ddaSDan Williams * to be sure that once the TMF request completes, the I/O that the 3056f231ddaSDan Williams * TMF was aborting is guaranteed to have completed. 3066f231ddaSDan Williams */ 3076f231ddaSDan Williams struct completion *io_request_completion; 30867ea838dSDan Williams struct scic_sds_request sci; 3096f231ddaSDan Williams }; 3106f231ddaSDan Williams 31167ea838dSDan Williams static inline struct isci_request *sci_req_to_ireq(struct scic_sds_request *sci_req) 31267ea838dSDan Williams { 31367ea838dSDan Williams struct isci_request *ireq = container_of(sci_req, typeof(*ireq), sci); 31467ea838dSDan Williams 31567ea838dSDan Williams return ireq; 31667ea838dSDan Williams } 31767ea838dSDan Williams 3186f231ddaSDan Williams /** 319f1f52e75SDan Williams * enum sci_base_request_states - This enumeration depicts all the states for 320f1f52e75SDan Williams * the common request state machine. 321f1f52e75SDan Williams * 322f1f52e75SDan Williams * 323f1f52e75SDan Williams */ 324f1f52e75SDan Williams enum sci_base_request_states { 325f1f52e75SDan Williams /** 326f1f52e75SDan Williams * Simply the initial state for the base request state machine. 327f1f52e75SDan Williams */ 328f1f52e75SDan Williams SCI_BASE_REQUEST_STATE_INITIAL, 329f1f52e75SDan Williams 330f1f52e75SDan Williams /** 331f1f52e75SDan Williams * This state indicates that the request has been constructed. This state 332f1f52e75SDan Williams * is entered from the INITIAL state. 333f1f52e75SDan Williams */ 334f1f52e75SDan Williams SCI_BASE_REQUEST_STATE_CONSTRUCTED, 335f1f52e75SDan Williams 336f1f52e75SDan Williams /** 337f1f52e75SDan Williams * This state indicates that the request has been started. This state is 338f1f52e75SDan Williams * entered from the CONSTRUCTED state. 339f1f52e75SDan Williams */ 340f1f52e75SDan Williams SCI_BASE_REQUEST_STATE_STARTED, 341f1f52e75SDan Williams 342*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE, 343*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE, 344*5dec6f4eSDan Williams 345*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE, 346*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE, 347*5dec6f4eSDan Williams 348*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE, 349*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE, 350*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE, 351*5dec6f4eSDan Williams 352*5dec6f4eSDan Williams /** 353*5dec6f4eSDan Williams * While in this state the IO request object is waiting for the TC completion 354*5dec6f4eSDan Williams * notification for the H2D Register FIS 355*5dec6f4eSDan Williams */ 356*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE, 357*5dec6f4eSDan Williams 358*5dec6f4eSDan Williams /** 359*5dec6f4eSDan Williams * While in this state the IO request object is waiting for either a PIO Setup 360*5dec6f4eSDan Williams * FIS or a D2H register FIS. The type of frame received is based on the 361*5dec6f4eSDan Williams * result of the prior frame and line conditions. 362*5dec6f4eSDan Williams */ 363*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE, 364*5dec6f4eSDan Williams 365*5dec6f4eSDan Williams /** 366*5dec6f4eSDan Williams * While in this state the IO request object is waiting for a DATA frame from 367*5dec6f4eSDan Williams * the device. 368*5dec6f4eSDan Williams */ 369*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE, 370*5dec6f4eSDan Williams 371*5dec6f4eSDan Williams /** 372*5dec6f4eSDan Williams * While in this state the IO request object is waiting to transmit the next data 373*5dec6f4eSDan Williams * frame to the device. 374*5dec6f4eSDan Williams */ 375*5dec6f4eSDan Williams SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE, 376*5dec6f4eSDan Williams 377f1f52e75SDan Williams /** 378f139303dSDan Williams * The AWAIT_TC_COMPLETION sub-state indicates that the started raw 379f139303dSDan Williams * task management request is waiting for the transmission of the 380f139303dSDan Williams * initial frame (i.e. command, task, etc.). 381f139303dSDan Williams */ 382f139303dSDan Williams SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION, 383f139303dSDan Williams 384f139303dSDan Williams /** 385f139303dSDan Williams * This sub-state indicates that the started task management request 386f139303dSDan Williams * is waiting for the reception of an unsolicited frame 387f139303dSDan Williams * (i.e. response IU). 388f139303dSDan Williams */ 389f139303dSDan Williams SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE, 390f139303dSDan Williams 391f139303dSDan Williams /** 392c72086e3SDan Williams * This sub-state indicates that the started task management request 393c72086e3SDan Williams * is waiting for the reception of an unsolicited frame 394c72086e3SDan Williams * (i.e. response IU). 395c72086e3SDan Williams */ 396c72086e3SDan Williams SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE, 397c72086e3SDan Williams 398c72086e3SDan Williams /** 399c72086e3SDan Williams * The AWAIT_TC_COMPLETION sub-state indicates that the started SMP request is 400c72086e3SDan Williams * waiting for the transmission of the initial frame (i.e. command, task, etc.). 401c72086e3SDan Williams */ 402c72086e3SDan Williams SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION, 403c72086e3SDan Williams 404c72086e3SDan Williams /** 405f1f52e75SDan Williams * This state indicates that the request has completed. 406f1f52e75SDan Williams * This state is entered from the STARTED state. This state is entered from 407f1f52e75SDan Williams * the ABORTING state. 408f1f52e75SDan Williams */ 409f1f52e75SDan Williams SCI_BASE_REQUEST_STATE_COMPLETED, 410f1f52e75SDan Williams 411f1f52e75SDan Williams /** 412f1f52e75SDan Williams * This state indicates that the request is in the process of being 413f1f52e75SDan Williams * terminated/aborted. 414f1f52e75SDan Williams * This state is entered from the CONSTRUCTED state. 415f1f52e75SDan Williams * This state is entered from the STARTED state. 416f1f52e75SDan Williams */ 417f1f52e75SDan Williams SCI_BASE_REQUEST_STATE_ABORTING, 418f1f52e75SDan Williams 419f1f52e75SDan Williams /** 420f1f52e75SDan Williams * Simply the final state for the base request state machine. 421f1f52e75SDan Williams */ 422f1f52e75SDan Williams SCI_BASE_REQUEST_STATE_FINAL, 423f1f52e75SDan Williams }; 424f1f52e75SDan Williams 425f1f52e75SDan Williams typedef enum sci_status (*scic_sds_io_request_handler_t) 426f1f52e75SDan Williams (struct scic_sds_request *request); 427f1f52e75SDan Williams typedef enum sci_status (*scic_sds_io_request_frame_handler_t) 428f1f52e75SDan Williams (struct scic_sds_request *req, u32 frame); 429f1f52e75SDan Williams typedef enum sci_status (*scic_sds_io_request_event_handler_t) 430f1f52e75SDan Williams (struct scic_sds_request *req, u32 event); 431f1f52e75SDan Williams typedef enum sci_status (*scic_sds_io_request_task_completion_handler_t) 432f1f52e75SDan Williams (struct scic_sds_request *req, u32 completion_code); 433f1f52e75SDan Williams 434f1f52e75SDan Williams /** 435f1f52e75SDan Williams * struct scic_sds_io_request_state_handler - This is the SDS core definition 436f1f52e75SDan Williams * of the state handlers. 437f1f52e75SDan Williams * 438f1f52e75SDan Williams * 439f1f52e75SDan Williams */ 440f1f52e75SDan Williams struct scic_sds_io_request_state_handler { 441f1f52e75SDan Williams /** 442f1f52e75SDan Williams * The start_handler specifies the method invoked when a user attempts to 443f1f52e75SDan Williams * start a request. 444f1f52e75SDan Williams */ 445f1f52e75SDan Williams scic_sds_io_request_handler_t start_handler; 446f1f52e75SDan Williams 447f1f52e75SDan Williams /** 448f1f52e75SDan Williams * The abort_handler specifies the method invoked when a user attempts to 449f1f52e75SDan Williams * abort a request. 450f1f52e75SDan Williams */ 451f1f52e75SDan Williams scic_sds_io_request_handler_t abort_handler; 452f1f52e75SDan Williams 453f1f52e75SDan Williams /** 454f1f52e75SDan Williams * The complete_handler specifies the method invoked when a user attempts to 455f1f52e75SDan Williams * complete a request. 456f1f52e75SDan Williams */ 457f1f52e75SDan Williams scic_sds_io_request_handler_t complete_handler; 458f1f52e75SDan Williams 459f1f52e75SDan Williams scic_sds_io_request_task_completion_handler_t tc_completion_handler; 460f1f52e75SDan Williams scic_sds_io_request_event_handler_t event_handler; 461f1f52e75SDan Williams scic_sds_io_request_frame_handler_t frame_handler; 462f1f52e75SDan Williams 463f1f52e75SDan Williams }; 464f1f52e75SDan Williams 465f1f52e75SDan Williams /** 466f1f52e75SDan Williams * scic_sds_request_get_controller() - 467f1f52e75SDan Williams * 468f1f52e75SDan Williams * This macro will return the controller for this io request object 469f1f52e75SDan Williams */ 470f1f52e75SDan Williams #define scic_sds_request_get_controller(sci_req) \ 471f1f52e75SDan Williams ((sci_req)->owning_controller) 472f1f52e75SDan Williams 473f1f52e75SDan Williams /** 474f1f52e75SDan Williams * scic_sds_request_get_device() - 475f1f52e75SDan Williams * 476f1f52e75SDan Williams * This macro will return the device for this io request object 477f1f52e75SDan Williams */ 478f1f52e75SDan Williams #define scic_sds_request_get_device(sci_req) \ 479f1f52e75SDan Williams ((sci_req)->target_device) 480f1f52e75SDan Williams 481f1f52e75SDan Williams /** 482f1f52e75SDan Williams * scic_sds_request_get_port() - 483f1f52e75SDan Williams * 484f1f52e75SDan Williams * This macro will return the port for this io request object 485f1f52e75SDan Williams */ 486f1f52e75SDan Williams #define scic_sds_request_get_port(sci_req) \ 487f1f52e75SDan Williams scic_sds_remote_device_get_port(scic_sds_request_get_device(sci_req)) 488f1f52e75SDan Williams 489f1f52e75SDan Williams /** 490f1f52e75SDan Williams * scic_sds_request_get_post_context() - 491f1f52e75SDan Williams * 492f1f52e75SDan Williams * This macro returns the constructed post context result for the io request. 493f1f52e75SDan Williams */ 494f1f52e75SDan Williams #define scic_sds_request_get_post_context(sci_req) \ 495f1f52e75SDan Williams ((sci_req)->post_context) 496f1f52e75SDan Williams 497f1f52e75SDan Williams /** 498f1f52e75SDan Williams * scic_sds_request_get_task_context() - 499f1f52e75SDan Williams * 500f1f52e75SDan Williams * This is a helper macro to return the os handle for this request object. 501f1f52e75SDan Williams */ 502f1f52e75SDan Williams #define scic_sds_request_get_task_context(request) \ 503f1f52e75SDan Williams ((request)->task_context_buffer) 504f1f52e75SDan Williams 505f1f52e75SDan Williams /** 506f1f52e75SDan Williams * scic_sds_request_set_status() - 507f1f52e75SDan Williams * 508f1f52e75SDan Williams * This macro will set the scu hardware status and sci request completion 509f1f52e75SDan Williams * status for an io request. 510f1f52e75SDan Williams */ 511f1f52e75SDan Williams #define scic_sds_request_set_status(request, scu_status_code, sci_status_code) \ 512f1f52e75SDan Williams { \ 513f1f52e75SDan Williams (request)->scu_status = (scu_status_code); \ 514f1f52e75SDan Williams (request)->sci_status = (sci_status_code); \ 515f1f52e75SDan Williams } 516f1f52e75SDan Williams 517f1f52e75SDan Williams #define scic_sds_request_complete(a_request) \ 518f1f52e75SDan Williams ((a_request)->state_handlers->complete_handler(a_request)) 519f1f52e75SDan Williams 520f1f52e75SDan Williams 521f1f52e75SDan Williams extern enum sci_status 522f1f52e75SDan Williams scic_sds_io_request_tc_completion(struct scic_sds_request *request, u32 completion_code); 523f1f52e75SDan Williams 524f1f52e75SDan Williams /** 525f1f52e75SDan Williams * SCU_SGL_ZERO() - 526f1f52e75SDan Williams * 527f1f52e75SDan Williams * This macro zeros the hardware SGL element data 528f1f52e75SDan Williams */ 529f1f52e75SDan Williams #define SCU_SGL_ZERO(scu_sge) \ 530f1f52e75SDan Williams { \ 531f1f52e75SDan Williams (scu_sge).length = 0; \ 532f1f52e75SDan Williams (scu_sge).address_lower = 0; \ 533f1f52e75SDan Williams (scu_sge).address_upper = 0; \ 534f1f52e75SDan Williams (scu_sge).address_modifier = 0; \ 535f1f52e75SDan Williams } 536f1f52e75SDan Williams 537f1f52e75SDan Williams /** 538f1f52e75SDan Williams * SCU_SGL_COPY() - 539f1f52e75SDan Williams * 540f1f52e75SDan Williams * This macro copys the SGL Element data from the host os to the hardware SGL 541f1f52e75SDan Williams * elment data 542f1f52e75SDan Williams */ 543f1f52e75SDan Williams #define SCU_SGL_COPY(scu_sge, os_sge) \ 544f1f52e75SDan Williams { \ 545f1f52e75SDan Williams (scu_sge).length = sg_dma_len(sg); \ 546f1f52e75SDan Williams (scu_sge).address_upper = \ 547f1f52e75SDan Williams upper_32_bits(sg_dma_address(sg)); \ 548f1f52e75SDan Williams (scu_sge).address_lower = \ 549f1f52e75SDan Williams lower_32_bits(sg_dma_address(sg)); \ 550f1f52e75SDan Williams (scu_sge).address_modifier = 0; \ 551f1f52e75SDan Williams } 552f1f52e75SDan Williams 553f1f52e75SDan Williams enum sci_status scic_sds_request_start(struct scic_sds_request *sci_req); 554f1f52e75SDan Williams enum sci_status scic_sds_io_request_terminate(struct scic_sds_request *sci_req); 555f1f52e75SDan Williams enum sci_status scic_sds_io_request_event_handler(struct scic_sds_request *sci_req, 556f1f52e75SDan Williams u32 event_code); 557f1f52e75SDan Williams enum sci_status scic_sds_io_request_frame_handler(struct scic_sds_request *sci_req, 558f1f52e75SDan Williams u32 frame_index); 559f1f52e75SDan Williams enum sci_status scic_sds_task_request_terminate(struct scic_sds_request *sci_req); 560f1f52e75SDan Williams 561f1f52e75SDan Williams /* XXX open code in caller */ 562f1f52e75SDan Williams static inline void *scic_request_get_virt_addr(struct scic_sds_request *sci_req, 563f1f52e75SDan Williams dma_addr_t phys_addr) 564f1f52e75SDan Williams { 565f1f52e75SDan Williams struct isci_request *ireq = sci_req_to_ireq(sci_req); 566f1f52e75SDan Williams dma_addr_t offset; 567f1f52e75SDan Williams 568f1f52e75SDan Williams BUG_ON(phys_addr < ireq->request_daddr); 569f1f52e75SDan Williams 570f1f52e75SDan Williams offset = phys_addr - ireq->request_daddr; 571f1f52e75SDan Williams 572f1f52e75SDan Williams BUG_ON(offset >= sizeof(*ireq)); 573f1f52e75SDan Williams 574f1f52e75SDan Williams return (char *)ireq + offset; 575f1f52e75SDan Williams } 576f1f52e75SDan Williams 577f1f52e75SDan Williams /* XXX open code in caller */ 578f1f52e75SDan Williams static inline dma_addr_t scic_io_request_get_dma_addr(struct scic_sds_request *sci_req, 579f1f52e75SDan Williams void *virt_addr) 580f1f52e75SDan Williams { 581f1f52e75SDan Williams struct isci_request *ireq = sci_req_to_ireq(sci_req); 582f1f52e75SDan Williams 583f1f52e75SDan Williams char *requested_addr = (char *)virt_addr; 584f1f52e75SDan Williams char *base_addr = (char *)ireq; 585f1f52e75SDan Williams 586f1f52e75SDan Williams BUG_ON(requested_addr < base_addr); 587f1f52e75SDan Williams BUG_ON((requested_addr - base_addr) >= sizeof(*ireq)); 588f1f52e75SDan Williams 589f1f52e75SDan Williams return ireq->request_daddr + (requested_addr - base_addr); 590f1f52e75SDan Williams } 591f1f52e75SDan Williams 592f1f52e75SDan Williams /** 5936f231ddaSDan Williams * This function gets the status of the request object. 5946f231ddaSDan Williams * @request: This parameter points to the isci_request object 5956f231ddaSDan Williams * 5966f231ddaSDan Williams * status of the object as a isci_request_status enum. 5976f231ddaSDan Williams */ 5986f231ddaSDan Williams static inline 5996f231ddaSDan Williams enum isci_request_status isci_request_get_state( 6006f231ddaSDan Williams struct isci_request *isci_request) 6016f231ddaSDan Williams { 6026f231ddaSDan Williams BUG_ON(isci_request == NULL); 6036f231ddaSDan Williams 6046f231ddaSDan Williams /*probably a bad sign... */ 6056f231ddaSDan Williams if (isci_request->status == unallocated) 6066f231ddaSDan Williams dev_warn(&isci_request->isci_host->pdev->dev, 6076f231ddaSDan Williams "%s: isci_request->status == unallocated\n", 6086f231ddaSDan Williams __func__); 6096f231ddaSDan Williams 6106f231ddaSDan Williams return isci_request->status; 6116f231ddaSDan Williams } 6126f231ddaSDan Williams 6136f231ddaSDan Williams 6146f231ddaSDan Williams /** 6156f231ddaSDan Williams * isci_request_change_state() - This function sets the status of the request 6166f231ddaSDan Williams * object. 6176f231ddaSDan Williams * @request: This parameter points to the isci_request object 6186f231ddaSDan Williams * @status: This Parameter is the new status of the object 6196f231ddaSDan Williams * 6206f231ddaSDan Williams */ 6216f231ddaSDan Williams static inline enum isci_request_status isci_request_change_state( 6226f231ddaSDan Williams struct isci_request *isci_request, 6236f231ddaSDan Williams enum isci_request_status status) 6246f231ddaSDan Williams { 6256f231ddaSDan Williams enum isci_request_status old_state; 6266f231ddaSDan Williams unsigned long flags; 6276f231ddaSDan Williams 6286f231ddaSDan Williams dev_dbg(&isci_request->isci_host->pdev->dev, 6296f231ddaSDan Williams "%s: isci_request = %p, state = 0x%x\n", 6306f231ddaSDan Williams __func__, 6316f231ddaSDan Williams isci_request, 6326f231ddaSDan Williams status); 6336f231ddaSDan Williams 6346f231ddaSDan Williams BUG_ON(isci_request == NULL); 6356f231ddaSDan Williams 6366f231ddaSDan Williams spin_lock_irqsave(&isci_request->state_lock, flags); 6376f231ddaSDan Williams old_state = isci_request->status; 6386f231ddaSDan Williams isci_request->status = status; 6396f231ddaSDan Williams spin_unlock_irqrestore(&isci_request->state_lock, flags); 6406f231ddaSDan Williams 6416f231ddaSDan Williams return old_state; 6426f231ddaSDan Williams } 6436f231ddaSDan Williams 6446f231ddaSDan Williams /** 6456f231ddaSDan Williams * isci_request_change_started_to_newstate() - This function sets the status of 6466f231ddaSDan Williams * the request object. 6476f231ddaSDan Williams * @request: This parameter points to the isci_request object 6486f231ddaSDan Williams * @status: This Parameter is the new status of the object 6496f231ddaSDan Williams * 6506f231ddaSDan Williams * state previous to any change. 6516f231ddaSDan Williams */ 6526f231ddaSDan Williams static inline enum isci_request_status isci_request_change_started_to_newstate( 6536f231ddaSDan Williams struct isci_request *isci_request, 6546f231ddaSDan Williams struct completion *completion_ptr, 6556f231ddaSDan Williams enum isci_request_status newstate) 6566f231ddaSDan Williams { 6576f231ddaSDan Williams enum isci_request_status old_state; 6586f231ddaSDan Williams unsigned long flags; 6596f231ddaSDan Williams 6606f231ddaSDan Williams spin_lock_irqsave(&isci_request->state_lock, flags); 6616f231ddaSDan Williams 6626f231ddaSDan Williams old_state = isci_request->status; 6636f231ddaSDan Williams 664f219f010SJeff Skirvin if (old_state == started || old_state == aborting) { 6656f231ddaSDan Williams BUG_ON(isci_request->io_request_completion != NULL); 6666f231ddaSDan Williams 6676f231ddaSDan Williams isci_request->io_request_completion = completion_ptr; 6686f231ddaSDan Williams isci_request->status = newstate; 6696f231ddaSDan Williams } 6706f231ddaSDan Williams spin_unlock_irqrestore(&isci_request->state_lock, flags); 6716f231ddaSDan Williams 6726f231ddaSDan Williams dev_dbg(&isci_request->isci_host->pdev->dev, 6736f231ddaSDan Williams "%s: isci_request = %p, old_state = 0x%x\n", 6746f231ddaSDan Williams __func__, 6756f231ddaSDan Williams isci_request, 6766f231ddaSDan Williams old_state); 6776f231ddaSDan Williams 6786f231ddaSDan Williams return old_state; 6796f231ddaSDan Williams } 6806f231ddaSDan Williams 6816f231ddaSDan Williams /** 6826f231ddaSDan Williams * isci_request_change_started_to_aborted() - This function sets the status of 6836f231ddaSDan Williams * the request object. 6846f231ddaSDan Williams * @request: This parameter points to the isci_request object 6856f231ddaSDan Williams * @completion_ptr: This parameter is saved as the kernel completion structure 6866f231ddaSDan Williams * signalled when the old request completes. 6876f231ddaSDan Williams * 6886f231ddaSDan Williams * state previous to any change. 6896f231ddaSDan Williams */ 6906f231ddaSDan Williams static inline enum isci_request_status isci_request_change_started_to_aborted( 6916f231ddaSDan Williams struct isci_request *isci_request, 6926f231ddaSDan Williams struct completion *completion_ptr) 6936f231ddaSDan Williams { 6946f231ddaSDan Williams return isci_request_change_started_to_newstate( 6956f231ddaSDan Williams isci_request, completion_ptr, aborted 6966f231ddaSDan Williams ); 6976f231ddaSDan Williams } 6986f231ddaSDan Williams /** 6996f231ddaSDan Williams * isci_request_free() - This function frees the request object. 7006f231ddaSDan Williams * @isci_host: This parameter specifies the ISCI host object 7016f231ddaSDan Williams * @isci_request: This parameter points to the isci_request object 7026f231ddaSDan Williams * 7036f231ddaSDan Williams */ 7046f231ddaSDan Williams static inline void isci_request_free( 7056f231ddaSDan Williams struct isci_host *isci_host, 7066f231ddaSDan Williams struct isci_request *isci_request) 7076f231ddaSDan Williams { 7086cb4d6b3SBartosz Barcinski if (!isci_request) 7096cb4d6b3SBartosz Barcinski return; 7106f231ddaSDan Williams 7116f231ddaSDan Williams /* release the dma memory if we fail. */ 7126f231ddaSDan Williams dma_pool_free(isci_host->dma_pool, isci_request, 7136f231ddaSDan Williams isci_request->request_daddr); 7146f231ddaSDan Williams } 7156f231ddaSDan Williams 7166f231ddaSDan Williams 7176f231ddaSDan Williams /* #define ISCI_REQUEST_VALIDATE_ACCESS 7186f231ddaSDan Williams */ 7196f231ddaSDan Williams 7206f231ddaSDan Williams #ifdef ISCI_REQUEST_VALIDATE_ACCESS 7216f231ddaSDan Williams 7226f231ddaSDan Williams static inline 7236f231ddaSDan Williams struct sas_task *isci_request_access_task(struct isci_request *isci_request) 7246f231ddaSDan Williams { 7256f231ddaSDan Williams BUG_ON(isci_request->ttype != io_task); 7266f231ddaSDan Williams return isci_request->ttype_ptr.io_task_ptr; 7276f231ddaSDan Williams } 7286f231ddaSDan Williams 7296f231ddaSDan Williams static inline 7306f231ddaSDan Williams struct isci_tmf *isci_request_access_tmf(struct isci_request *isci_request) 7316f231ddaSDan Williams { 7326f231ddaSDan Williams BUG_ON(isci_request->ttype != tmf_task); 7336f231ddaSDan Williams return isci_request->ttype_ptr.tmf_task_ptr; 7346f231ddaSDan Williams } 7356f231ddaSDan Williams 7366f231ddaSDan Williams #else /* not ISCI_REQUEST_VALIDATE_ACCESS */ 7376f231ddaSDan Williams 7386f231ddaSDan Williams #define isci_request_access_task(RequestPtr) \ 7396f231ddaSDan Williams ((RequestPtr)->ttype_ptr.io_task_ptr) 7406f231ddaSDan Williams 7416f231ddaSDan Williams #define isci_request_access_tmf(RequestPtr) \ 7426f231ddaSDan Williams ((RequestPtr)->ttype_ptr.tmf_task_ptr) 7436f231ddaSDan Williams 7446f231ddaSDan Williams #endif /* not ISCI_REQUEST_VALIDATE_ACCESS */ 7456f231ddaSDan Williams 7466f231ddaSDan Williams 7476f231ddaSDan Williams int isci_request_alloc_tmf( 7486f231ddaSDan Williams struct isci_host *isci_host, 7496f231ddaSDan Williams struct isci_tmf *isci_tmf, 7506f231ddaSDan Williams struct isci_request **isci_request, 7516f231ddaSDan Williams struct isci_remote_device *isci_device, 7526f231ddaSDan Williams gfp_t gfp_flags); 7536f231ddaSDan Williams 7546f231ddaSDan Williams 7556f231ddaSDan Williams int isci_request_execute( 7566f231ddaSDan Williams struct isci_host *isci_host, 7576f231ddaSDan Williams struct sas_task *task, 7586f231ddaSDan Williams struct isci_request **request, 7596f231ddaSDan Williams gfp_t gfp_flags); 7606f231ddaSDan Williams 7616f231ddaSDan Williams /** 7626f231ddaSDan Williams * isci_request_unmap_sgl() - This function unmaps the DMA address of a given 7636f231ddaSDan Williams * sgl 7646f231ddaSDan Williams * @request: This parameter points to the isci_request object 7656f231ddaSDan Williams * @*pdev: This Parameter is the pci_device struct for the controller 7666f231ddaSDan Williams * 7676f231ddaSDan Williams */ 7686f231ddaSDan Williams static inline void isci_request_unmap_sgl( 7696f231ddaSDan Williams struct isci_request *request, 7706f231ddaSDan Williams struct pci_dev *pdev) 7716f231ddaSDan Williams { 7726f231ddaSDan Williams struct sas_task *task = isci_request_access_task(request); 7736f231ddaSDan Williams 7746f231ddaSDan Williams dev_dbg(&request->isci_host->pdev->dev, 7756f231ddaSDan Williams "%s: request = %p, task = %p,\n" 7766f231ddaSDan Williams "task->data_dir = %d, is_sata = %d\n ", 7776f231ddaSDan Williams __func__, 7786f231ddaSDan Williams request, 7796f231ddaSDan Williams task, 7806f231ddaSDan Williams task->data_dir, 7816f231ddaSDan Williams sas_protocol_ata(task->task_proto)); 7826f231ddaSDan Williams 7836f231ddaSDan Williams if ((task->data_dir != PCI_DMA_NONE) && 7846f231ddaSDan Williams !sas_protocol_ata(task->task_proto)) { 7856f231ddaSDan Williams if (task->num_scatter == 0) 7866f231ddaSDan Williams /* 0 indicates a single dma address */ 7876f231ddaSDan Williams dma_unmap_single( 7886f231ddaSDan Williams &pdev->dev, 7896f231ddaSDan Williams request->zero_scatter_daddr, 7906f231ddaSDan Williams task->total_xfer_len, 7916f231ddaSDan Williams task->data_dir 7926f231ddaSDan Williams ); 7936f231ddaSDan Williams 7946f231ddaSDan Williams else /* unmap the sgl dma addresses */ 7956f231ddaSDan Williams dma_unmap_sg( 7966f231ddaSDan Williams &pdev->dev, 7976f231ddaSDan Williams task->scatter, 7986f231ddaSDan Williams request->num_sg_entries, 7996f231ddaSDan Williams task->data_dir 8006f231ddaSDan Williams ); 8016f231ddaSDan Williams } 8026f231ddaSDan Williams } 8036f231ddaSDan Williams 8046f231ddaSDan Williams /** 8056f231ddaSDan Williams * isci_request_io_request_get_next_sge() - This function is called by the sci 8066f231ddaSDan Williams * core to retrieve the next sge for a given request. 8076f231ddaSDan Williams * @request: This parameter is the isci_request object. 8086f231ddaSDan Williams * @current_sge_address: This parameter is the last sge retrieved by the sci 8096f231ddaSDan Williams * core for this request. 8106f231ddaSDan Williams * 8116f231ddaSDan Williams * pointer to the next sge for specified request. 8126f231ddaSDan Williams */ 8136f231ddaSDan Williams static inline void *isci_request_io_request_get_next_sge( 8146f231ddaSDan Williams struct isci_request *request, 8156f231ddaSDan Williams void *current_sge_address) 8166f231ddaSDan Williams { 8176f231ddaSDan Williams struct sas_task *task = isci_request_access_task(request); 8186f231ddaSDan Williams void *ret = NULL; 8196f231ddaSDan Williams 8206f231ddaSDan Williams dev_dbg(&request->isci_host->pdev->dev, 8216f231ddaSDan Williams "%s: request = %p, " 8226f231ddaSDan Williams "current_sge_address = %p, " 8236f231ddaSDan Williams "num_scatter = %d\n", 8246f231ddaSDan Williams __func__, 8256f231ddaSDan Williams request, 8266f231ddaSDan Williams current_sge_address, 8276f231ddaSDan Williams task->num_scatter); 8286f231ddaSDan Williams 8296f231ddaSDan Williams if (!current_sge_address) /* First time through.. */ 8306f231ddaSDan Williams ret = task->scatter; /* always task->scatter */ 8316f231ddaSDan Williams else if (task->num_scatter == 0) /* Next element, if num_scatter == 0 */ 8326f231ddaSDan Williams ret = NULL; /* there is only one element. */ 8336f231ddaSDan Williams else 8346f231ddaSDan Williams ret = sg_next(current_sge_address); /* sg_next returns NULL 8356f231ddaSDan Williams * for the last element 8366f231ddaSDan Williams */ 8376f231ddaSDan Williams 8386f231ddaSDan Williams dev_dbg(&request->isci_host->pdev->dev, 8396f231ddaSDan Williams "%s: next sge address = %p\n", 8406f231ddaSDan Williams __func__, 8416f231ddaSDan Williams ret); 8426f231ddaSDan Williams 8436f231ddaSDan Williams return ret; 8446f231ddaSDan Williams } 8456f231ddaSDan Williams 846f1f52e75SDan Williams void isci_terminate_pending_requests(struct isci_host *isci_host, 8476f231ddaSDan Williams struct isci_remote_device *isci_device, 8486f231ddaSDan Williams enum isci_request_status new_request_state); 849f1f52e75SDan Williams enum sci_status scic_task_request_construct(struct scic_sds_controller *scic, 850f1f52e75SDan Williams struct scic_sds_remote_device *sci_dev, 851f1f52e75SDan Williams u16 io_tag, 852f1f52e75SDan Williams struct scic_sds_request *sci_req); 853f1f52e75SDan Williams enum sci_status scic_task_request_construct_ssp(struct scic_sds_request *sci_req); 854f1f52e75SDan Williams enum sci_status scic_task_request_construct_sata(struct scic_sds_request *sci_req); 855*5dec6f4eSDan Williams enum sci_status scic_sds_stp_udma_request_construct(struct scic_sds_request *sci_req, 856*5dec6f4eSDan Williams u32 transfer_length, 857*5dec6f4eSDan Williams enum dma_data_direction dir); 858f1f52e75SDan Williams void scic_stp_io_request_set_ncq_tag(struct scic_sds_request *sci_req, u16 ncq_tag); 859f1f52e75SDan Williams void scic_sds_smp_request_copy_response(struct scic_sds_request *sci_req); 8606f231ddaSDan Williams #endif /* !defined(_ISCI_REQUEST_H_) */ 861