xref: /openbmc/linux/drivers/scsi/isci/request.h (revision 89a7301f21fb00e753089671eb9e4132aab8ea08)
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 
92ba7cb223SDan Williams /**
93ba7cb223SDan Williams  * isci_stp_request - extra request infrastructure to handle pio/atapi protocol
94ba7cb223SDan Williams  * @pio_len - number of bytes requested at PIO setup
95ba7cb223SDan Williams  * @status - pio setup ending status value to tell us if we need
96ba7cb223SDan Williams  *	     to wait for another fis or if the transfer is complete.  Upon
97ba7cb223SDan Williams  *           receipt of a d2h fis this will be the status field of that fis.
98ba7cb223SDan Williams  * @sgl - track pio transfer progress as we iterate through the sgl
99ba7cb223SDan Williams  * @device_cdb_len - atapi device advertises it's transfer constraints at setup
1005dec6f4eSDan Williams  */
101ba7cb223SDan Williams struct isci_stp_request {
102ba7cb223SDan Williams 	u32 pio_len;
103ba7cb223SDan Williams 	u8 status;
1045dec6f4eSDan Williams 
105ba7cb223SDan Williams 	struct isci_stp_pio_sgl {
106ba7cb223SDan Williams 		int index;
107ba7cb223SDan Williams 		u8 set;
108ba7cb223SDan Williams 		u32 offset;
109ba7cb223SDan Williams 	} sgl;
110ba7cb223SDan Williams 	u32 device_cdb_len;
1115dec6f4eSDan Williams };
1125dec6f4eSDan Williams 
1135076a1a9SDan Williams struct isci_request {
1145076a1a9SDan Williams 	enum isci_request_status status;
1155076a1a9SDan Williams 	#define IREQ_COMPLETE_IN_TARGET 0
1165076a1a9SDan Williams 	#define IREQ_TERMINATED 1
1175076a1a9SDan Williams 	#define IREQ_TMF 2
1185076a1a9SDan Williams 	#define IREQ_ACTIVE 3
1195076a1a9SDan Williams 	unsigned long flags;
1205076a1a9SDan Williams 	/* XXX kill ttype and ttype_ptr, allocate full sas_task */
1215076a1a9SDan Williams 	enum task_type ttype;
1225076a1a9SDan Williams 	union ttype_ptr_union {
1235076a1a9SDan Williams 		struct sas_task *io_task_ptr;   /* When ttype==io_task  */
1245076a1a9SDan Williams 		struct isci_tmf *tmf_task_ptr;  /* When ttype==tmf_task */
1255076a1a9SDan Williams 	} ttype_ptr;
1265076a1a9SDan Williams 	struct isci_host *isci_host;
1275076a1a9SDan Williams 	/* For use in the requests_to_{complete|abort} lists: */
1285076a1a9SDan Williams 	struct list_head completed_node;
1295076a1a9SDan Williams 	/* For use in the reqs_in_process list: */
1305076a1a9SDan Williams 	struct list_head dev_node;
1315076a1a9SDan Williams 	spinlock_t state_lock;
1325076a1a9SDan Williams 	dma_addr_t request_daddr;
1335076a1a9SDan Williams 	dma_addr_t zero_scatter_daddr;
1345076a1a9SDan Williams 	unsigned int num_sg_entries;
1355076a1a9SDan Williams 	/* Note: "io_request_completion" is completed in two different ways
1365076a1a9SDan Williams 	 * depending on whether this is a TMF or regular request.
1375076a1a9SDan Williams 	 * - TMF requests are completed in the thread that started them;
1385076a1a9SDan Williams 	 * - regular requests are completed in the request completion callback
1395076a1a9SDan Williams 	 *   function.
1405076a1a9SDan Williams 	 * This difference in operation allows the aborter of a TMF request
1415076a1a9SDan Williams 	 * to be sure that once the TMF request completes, the I/O that the
1425076a1a9SDan Williams 	 * TMF was aborting is guaranteed to have completed.
1435076a1a9SDan Williams 	 *
1445076a1a9SDan Williams 	 * XXX kill io_request_completion
145f1f52e75SDan Williams 	 */
1465076a1a9SDan Williams 	struct completion *io_request_completion;
147e301370aSEdmund Nadolski 	struct sci_base_state_machine sm;
148d9dcb4baSDan Williams 	struct isci_host *owning_controller;
14978a6f06eSDan Williams 	struct isci_remote_device *target_device;
150f1f52e75SDan Williams 	u16 io_tag;
151f1f52e75SDan Williams 	enum sci_request_protocol protocol;
1525076a1a9SDan Williams 	u32 scu_status; /* hardware result */
1535076a1a9SDan Williams 	u32 sci_status; /* upper layer disposition */
154f1f52e75SDan Williams 	u32 post_context;
155312e0c24SDan Williams 	struct scu_task_context *tc;
156f1f52e75SDan Williams 	/* could be larger with sg chaining */
1577c78da31SDan Williams 	#define SCU_SGL_SIZE ((SCI_MAX_SCATTER_GATHER_ELEMENTS + 1) / 2)
158f1f52e75SDan Williams 	struct scu_sgl_element_pair sg_table[SCU_SGL_SIZE] __attribute__ ((aligned(32)));
1595076a1a9SDan Williams 	/* This field is a pointer to the stored rx frame data.  It is used in
160e301370aSEdmund Nadolski 	 * STP internal requests and SMP response frames.  If this field is
161e301370aSEdmund Nadolski 	 * non-NULL the saved frame must be released on IO request completion.
162f1f52e75SDan Williams 	 */
163f1f52e75SDan Williams 	u32 saved_rx_frame_index;
164f1f52e75SDan Williams 
165f1f52e75SDan Williams 	union {
166f1f52e75SDan Williams 		struct {
167f1f52e75SDan Williams 			union {
168f1f52e75SDan Williams 				struct ssp_cmd_iu cmd;
169f1f52e75SDan Williams 				struct ssp_task_iu tmf;
170f1f52e75SDan Williams 			};
171f1f52e75SDan Williams 			union {
172f1f52e75SDan Williams 				struct ssp_response_iu rsp;
173f1f52e75SDan Williams 				u8 rsp_buf[SSP_RESP_IU_MAX_SIZE];
174f1f52e75SDan Williams 			};
175f1f52e75SDan Williams 		} ssp;
176f1f52e75SDan Williams 		struct {
177f1f52e75SDan Williams 			struct smp_resp rsp;
178f1f52e75SDan Williams 		} smp;
179f1f52e75SDan Williams 		struct {
180ba7cb223SDan Williams 			struct isci_stp_request req;
181f1f52e75SDan Williams 			struct host_to_dev_fis cmd;
182f1f52e75SDan Williams 			struct dev_to_host_fis rsp;
183f1f52e75SDan Williams 		} stp;
184f1f52e75SDan Williams 	};
185f1f52e75SDan Williams };
186f1f52e75SDan Williams 
1875076a1a9SDan Williams static inline struct isci_request *to_ireq(struct isci_stp_request *stp_req)
188f1f52e75SDan Williams {
1895076a1a9SDan Williams 	struct isci_request *ireq;
190f1f52e75SDan Williams 
1915076a1a9SDan Williams 	ireq = container_of(stp_req, typeof(*ireq), stp.req);
19267ea838dSDan Williams 	return ireq;
19367ea838dSDan Williams }
19467ea838dSDan Williams 
1956f231ddaSDan Williams /**
196f1f52e75SDan Williams  * enum sci_base_request_states - This enumeration depicts all the states for
197f1f52e75SDan Williams  *    the common request state machine.
198f1f52e75SDan Williams  *
199f1f52e75SDan Williams  *
200f1f52e75SDan Williams  */
201f1f52e75SDan Williams enum sci_base_request_states {
202e301370aSEdmund Nadolski 	/*
203f1f52e75SDan Williams 	 * Simply the initial state for the base request state machine.
204f1f52e75SDan Williams 	 */
205e301370aSEdmund Nadolski 	SCI_REQ_INIT,
206f1f52e75SDan Williams 
207e301370aSEdmund Nadolski 	/*
208e301370aSEdmund Nadolski 	 * This state indicates that the request has been constructed.
209e301370aSEdmund Nadolski 	 * This state is entered from the INITIAL state.
210f1f52e75SDan Williams 	 */
211e301370aSEdmund Nadolski 	SCI_REQ_CONSTRUCTED,
212f1f52e75SDan Williams 
213e301370aSEdmund Nadolski 	/*
214e301370aSEdmund Nadolski 	 * This state indicates that the request has been started. This state
215e301370aSEdmund Nadolski 	 * is entered from the CONSTRUCTED state.
216f1f52e75SDan Williams 	 */
217e301370aSEdmund Nadolski 	SCI_REQ_STARTED,
218f1f52e75SDan Williams 
219e301370aSEdmund Nadolski 	SCI_REQ_STP_UDMA_WAIT_TC_COMP,
220e301370aSEdmund Nadolski 	SCI_REQ_STP_UDMA_WAIT_D2H,
2215dec6f4eSDan Williams 
222e301370aSEdmund Nadolski 	SCI_REQ_STP_NON_DATA_WAIT_H2D,
223e301370aSEdmund Nadolski 	SCI_REQ_STP_NON_DATA_WAIT_D2H,
2245dec6f4eSDan Williams 
225e301370aSEdmund Nadolski 	SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED,
226e301370aSEdmund Nadolski 	SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG,
227e301370aSEdmund Nadolski 	SCI_REQ_STP_SOFT_RESET_WAIT_D2H,
2285dec6f4eSDan Williams 
229e301370aSEdmund Nadolski 	/*
230e301370aSEdmund Nadolski 	 * While in this state the IO request object is waiting for the TC
231e301370aSEdmund Nadolski 	 * completion notification for the H2D Register FIS
2325dec6f4eSDan Williams 	 */
233e301370aSEdmund Nadolski 	SCI_REQ_STP_PIO_WAIT_H2D,
2345dec6f4eSDan Williams 
235e301370aSEdmund Nadolski 	/*
236e301370aSEdmund Nadolski 	 * While in this state the IO request object is waiting for either a
237e301370aSEdmund Nadolski 	 * PIO Setup FIS or a D2H register FIS.  The type of frame received is
238e301370aSEdmund Nadolski 	 * based on the result of the prior frame and line conditions.
2395dec6f4eSDan Williams 	 */
240e301370aSEdmund Nadolski 	SCI_REQ_STP_PIO_WAIT_FRAME,
2415dec6f4eSDan Williams 
242e301370aSEdmund Nadolski 	/*
243e301370aSEdmund Nadolski 	 * While in this state the IO request object is waiting for a DATA
244e301370aSEdmund Nadolski 	 * frame from the device.
2455dec6f4eSDan Williams 	 */
246e301370aSEdmund Nadolski 	SCI_REQ_STP_PIO_DATA_IN,
2475dec6f4eSDan Williams 
248e301370aSEdmund Nadolski 	/*
249e301370aSEdmund Nadolski 	 * While in this state the IO request object is waiting to transmit
250e301370aSEdmund Nadolski 	 * the next data frame to the device.
2515dec6f4eSDan Williams 	 */
252e301370aSEdmund Nadolski 	SCI_REQ_STP_PIO_DATA_OUT,
2535dec6f4eSDan Williams 
254e301370aSEdmund Nadolski 	/*
255f139303dSDan Williams 	 * The AWAIT_TC_COMPLETION sub-state indicates that the started raw
256f139303dSDan Williams 	 * task management request is waiting for the transmission of the
257f139303dSDan Williams 	 * initial frame (i.e. command, task, etc.).
258f139303dSDan Williams 	 */
259e301370aSEdmund Nadolski 	SCI_REQ_TASK_WAIT_TC_COMP,
260f139303dSDan Williams 
261e301370aSEdmund Nadolski 	/*
262f139303dSDan Williams 	 * This sub-state indicates that the started task management request
263f139303dSDan Williams 	 * is waiting for the reception of an unsolicited frame
264f139303dSDan Williams 	 * (i.e. response IU).
265f139303dSDan Williams 	 */
266e301370aSEdmund Nadolski 	SCI_REQ_TASK_WAIT_TC_RESP,
267f139303dSDan Williams 
268e301370aSEdmund Nadolski 	/*
269c72086e3SDan Williams 	 * This sub-state indicates that the started task management request
270c72086e3SDan Williams 	 * is waiting for the reception of an unsolicited frame
271c72086e3SDan Williams 	 * (i.e. response IU).
272c72086e3SDan Williams 	 */
273e301370aSEdmund Nadolski 	SCI_REQ_SMP_WAIT_RESP,
274c72086e3SDan Williams 
275e301370aSEdmund Nadolski 	/*
276e301370aSEdmund Nadolski 	 * The AWAIT_TC_COMPLETION sub-state indicates that the started SMP
277e301370aSEdmund Nadolski 	 * request is waiting for the transmission of the initial frame
278e301370aSEdmund Nadolski 	 * (i.e. command, task, etc.).
279c72086e3SDan Williams 	 */
280e301370aSEdmund Nadolski 	SCI_REQ_SMP_WAIT_TC_COMP,
281c72086e3SDan Williams 
282e301370aSEdmund Nadolski 	/*
283f1f52e75SDan Williams 	 * This state indicates that the request has completed.
284e301370aSEdmund Nadolski 	 * This state is entered from the STARTED state. This state is entered
285e301370aSEdmund Nadolski 	 * from the ABORTING state.
286f1f52e75SDan Williams 	 */
287e301370aSEdmund Nadolski 	SCI_REQ_COMPLETED,
288f1f52e75SDan Williams 
289e301370aSEdmund Nadolski 	/*
290f1f52e75SDan Williams 	 * This state indicates that the request is in the process of being
291f1f52e75SDan Williams 	 * terminated/aborted.
292f1f52e75SDan Williams 	 * This state is entered from the CONSTRUCTED state.
293f1f52e75SDan Williams 	 * This state is entered from the STARTED state.
294f1f52e75SDan Williams 	 */
295e301370aSEdmund Nadolski 	SCI_REQ_ABORTING,
296f1f52e75SDan Williams 
297e301370aSEdmund Nadolski 	/*
298f1f52e75SDan Williams 	 * Simply the final state for the base request state machine.
299f1f52e75SDan Williams 	 */
300e301370aSEdmund Nadolski 	SCI_REQ_FINAL,
301f1f52e75SDan Williams };
302f1f52e75SDan Williams 
303f1f52e75SDan Williams /**
304*89a7301fSDan Williams  * sci_request_get_controller() -
305f1f52e75SDan Williams  *
306f1f52e75SDan Williams  * This macro will return the controller for this io request object
307f1f52e75SDan Williams  */
308*89a7301fSDan Williams #define sci_request_get_controller(ireq) \
3095076a1a9SDan Williams 	((ireq)->owning_controller)
310f1f52e75SDan Williams 
311f1f52e75SDan Williams /**
312*89a7301fSDan Williams  * sci_request_get_device() -
313f1f52e75SDan Williams  *
314f1f52e75SDan Williams  * This macro will return the device for this io request object
315f1f52e75SDan Williams  */
316*89a7301fSDan Williams #define sci_request_get_device(ireq) \
3175076a1a9SDan Williams 	((ireq)->target_device)
318f1f52e75SDan Williams 
319f1f52e75SDan Williams /**
320*89a7301fSDan Williams  * sci_request_get_port() -
321f1f52e75SDan Williams  *
322f1f52e75SDan Williams  * This macro will return the port for this io request object
323f1f52e75SDan Williams  */
324*89a7301fSDan Williams #define sci_request_get_port(ireq)	\
325*89a7301fSDan Williams 	sci_remote_device_get_port(sci_request_get_device(ireq))
326f1f52e75SDan Williams 
327f1f52e75SDan Williams /**
328*89a7301fSDan Williams  * sci_request_get_post_context() -
329f1f52e75SDan Williams  *
330f1f52e75SDan Williams  * This macro returns the constructed post context result for the io request.
331f1f52e75SDan Williams  */
332*89a7301fSDan Williams #define sci_request_get_post_context(ireq)	\
3335076a1a9SDan Williams 	((ireq)->post_context)
334f1f52e75SDan Williams 
335f1f52e75SDan Williams /**
336*89a7301fSDan Williams  * sci_request_get_task_context() -
337f1f52e75SDan Williams  *
338f1f52e75SDan Williams  * This is a helper macro to return the os handle for this request object.
339f1f52e75SDan Williams  */
340*89a7301fSDan Williams #define sci_request_get_task_context(request) \
341f1f52e75SDan Williams 	((request)->task_context_buffer)
342f1f52e75SDan Williams 
343f1f52e75SDan Williams /**
344*89a7301fSDan Williams  * sci_request_set_status() -
345f1f52e75SDan Williams  *
346f1f52e75SDan Williams  * This macro will set the scu hardware status and sci request completion
347f1f52e75SDan Williams  * status for an io request.
348f1f52e75SDan Williams  */
349*89a7301fSDan Williams #define sci_request_set_status(request, scu_status_code, sci_status_code) \
350f1f52e75SDan Williams 	{ \
351f1f52e75SDan Williams 		(request)->scu_status = (scu_status_code); \
352f1f52e75SDan Williams 		(request)->sci_status = (sci_status_code); \
353f1f52e75SDan Williams 	}
354f1f52e75SDan Williams 
355*89a7301fSDan Williams enum sci_status sci_request_start(struct isci_request *ireq);
356*89a7301fSDan Williams enum sci_status sci_io_request_terminate(struct isci_request *ireq);
357e301370aSEdmund Nadolski enum sci_status
358*89a7301fSDan Williams sci_io_request_event_handler(struct isci_request *ireq,
359f1f52e75SDan Williams 				  u32 event_code);
360e301370aSEdmund Nadolski enum sci_status
361*89a7301fSDan Williams sci_io_request_frame_handler(struct isci_request *ireq,
362f1f52e75SDan Williams 				  u32 frame_index);
363e301370aSEdmund Nadolski enum sci_status
364*89a7301fSDan Williams sci_task_request_terminate(struct isci_request *ireq);
365e301370aSEdmund Nadolski extern enum sci_status
366*89a7301fSDan Williams sci_request_complete(struct isci_request *ireq);
367e301370aSEdmund Nadolski extern enum sci_status
368*89a7301fSDan Williams sci_io_request_tc_completion(struct isci_request *ireq, u32 code);
369f1f52e75SDan Williams 
370f1f52e75SDan Williams /* XXX open code in caller */
371e301370aSEdmund Nadolski static inline dma_addr_t
372*89a7301fSDan Williams sci_io_request_get_dma_addr(struct isci_request *ireq, void *virt_addr)
373f1f52e75SDan Williams {
374f1f52e75SDan Williams 
375f1f52e75SDan Williams 	char *requested_addr = (char *)virt_addr;
376f1f52e75SDan Williams 	char *base_addr = (char *)ireq;
377f1f52e75SDan Williams 
378f1f52e75SDan Williams 	BUG_ON(requested_addr < base_addr);
379f1f52e75SDan Williams 	BUG_ON((requested_addr - base_addr) >= sizeof(*ireq));
380f1f52e75SDan Williams 
381f1f52e75SDan Williams 	return ireq->request_daddr + (requested_addr - base_addr);
382f1f52e75SDan Williams }
383f1f52e75SDan Williams 
384f1f52e75SDan Williams /**
3856f231ddaSDan Williams  * This function gets the status of the request object.
3866f231ddaSDan Williams  * @request: This parameter points to the isci_request object
3876f231ddaSDan Williams  *
3886f231ddaSDan Williams  * status of the object as a isci_request_status enum.
3896f231ddaSDan Williams  */
390e301370aSEdmund Nadolski static inline enum isci_request_status
391e301370aSEdmund Nadolski isci_request_get_state(struct isci_request *isci_request)
3926f231ddaSDan Williams {
3936f231ddaSDan Williams 	BUG_ON(isci_request == NULL);
3946f231ddaSDan Williams 
3956f231ddaSDan Williams 	/*probably a bad sign...	*/
3966f231ddaSDan Williams 	if (isci_request->status == unallocated)
3976f231ddaSDan Williams 		dev_warn(&isci_request->isci_host->pdev->dev,
3986f231ddaSDan Williams 			 "%s: isci_request->status == unallocated\n",
3996f231ddaSDan Williams 			 __func__);
4006f231ddaSDan Williams 
4016f231ddaSDan Williams 	return isci_request->status;
4026f231ddaSDan Williams }
4036f231ddaSDan Williams 
4046f231ddaSDan Williams 
4056f231ddaSDan Williams /**
4066f231ddaSDan Williams  * isci_request_change_state() - This function sets the status of the request
4076f231ddaSDan Williams  *    object.
4086f231ddaSDan Williams  * @request: This parameter points to the isci_request object
4096f231ddaSDan Williams  * @status: This Parameter is the new status of the object
4106f231ddaSDan Williams  *
4116f231ddaSDan Williams  */
412e301370aSEdmund Nadolski static inline enum isci_request_status
413e301370aSEdmund Nadolski isci_request_change_state(struct isci_request *isci_request,
4146f231ddaSDan Williams 			  enum isci_request_status status)
4156f231ddaSDan Williams {
4166f231ddaSDan Williams 	enum isci_request_status old_state;
4176f231ddaSDan Williams 	unsigned long flags;
4186f231ddaSDan Williams 
4196f231ddaSDan Williams 	dev_dbg(&isci_request->isci_host->pdev->dev,
4206f231ddaSDan Williams 		"%s: isci_request = %p, state = 0x%x\n",
4216f231ddaSDan Williams 		__func__,
4226f231ddaSDan Williams 		isci_request,
4236f231ddaSDan Williams 		status);
4246f231ddaSDan Williams 
4256f231ddaSDan Williams 	BUG_ON(isci_request == NULL);
4266f231ddaSDan Williams 
4276f231ddaSDan Williams 	spin_lock_irqsave(&isci_request->state_lock, flags);
4286f231ddaSDan Williams 	old_state = isci_request->status;
4296f231ddaSDan Williams 	isci_request->status = status;
4306f231ddaSDan Williams 	spin_unlock_irqrestore(&isci_request->state_lock, flags);
4316f231ddaSDan Williams 
4326f231ddaSDan Williams 	return old_state;
4336f231ddaSDan Williams }
4346f231ddaSDan Williams 
4356f231ddaSDan Williams /**
4366f231ddaSDan Williams  * isci_request_change_started_to_newstate() - This function sets the status of
4376f231ddaSDan Williams  *    the request object.
4386f231ddaSDan Williams  * @request: This parameter points to the isci_request object
4396f231ddaSDan Williams  * @status: This Parameter is the new status of the object
4406f231ddaSDan Williams  *
4416f231ddaSDan Williams  * state previous to any change.
4426f231ddaSDan Williams  */
443e301370aSEdmund Nadolski static inline enum isci_request_status
444e301370aSEdmund Nadolski isci_request_change_started_to_newstate(struct isci_request *isci_request,
4456f231ddaSDan Williams 					struct completion *completion_ptr,
4466f231ddaSDan Williams 					enum isci_request_status newstate)
4476f231ddaSDan Williams {
4486f231ddaSDan Williams 	enum isci_request_status old_state;
4496f231ddaSDan Williams 	unsigned long flags;
4506f231ddaSDan Williams 
4516f231ddaSDan Williams 	spin_lock_irqsave(&isci_request->state_lock, flags);
4526f231ddaSDan Williams 
4536f231ddaSDan Williams 	old_state = isci_request->status;
4546f231ddaSDan Williams 
455f219f010SJeff Skirvin 	if (old_state == started || old_state == aborting) {
4566f231ddaSDan Williams 		BUG_ON(isci_request->io_request_completion != NULL);
4576f231ddaSDan Williams 
4586f231ddaSDan Williams 		isci_request->io_request_completion = completion_ptr;
4596f231ddaSDan Williams 		isci_request->status = newstate;
4606f231ddaSDan Williams 	}
461e301370aSEdmund Nadolski 
4626f231ddaSDan Williams 	spin_unlock_irqrestore(&isci_request->state_lock, flags);
4636f231ddaSDan Williams 
4646f231ddaSDan Williams 	dev_dbg(&isci_request->isci_host->pdev->dev,
4656f231ddaSDan Williams 		"%s: isci_request = %p, old_state = 0x%x\n",
4666f231ddaSDan Williams 		__func__,
4676f231ddaSDan Williams 		isci_request,
4686f231ddaSDan Williams 		old_state);
4696f231ddaSDan Williams 
4706f231ddaSDan Williams 	return old_state;
4716f231ddaSDan Williams }
4726f231ddaSDan Williams 
4736f231ddaSDan Williams /**
4746f231ddaSDan Williams  * isci_request_change_started_to_aborted() - This function sets the status of
4756f231ddaSDan Williams  *    the request object.
4766f231ddaSDan Williams  * @request: This parameter points to the isci_request object
4776f231ddaSDan Williams  * @completion_ptr: This parameter is saved as the kernel completion structure
4786f231ddaSDan Williams  *    signalled when the old request completes.
4796f231ddaSDan Williams  *
4806f231ddaSDan Williams  * state previous to any change.
4816f231ddaSDan Williams  */
482e301370aSEdmund Nadolski static inline enum isci_request_status
483e301370aSEdmund Nadolski isci_request_change_started_to_aborted(struct isci_request *isci_request,
4846f231ddaSDan Williams 				       struct completion *completion_ptr)
4856f231ddaSDan Williams {
486e301370aSEdmund Nadolski 	return isci_request_change_started_to_newstate(isci_request,
487e301370aSEdmund Nadolski 						       completion_ptr,
488e301370aSEdmund Nadolski 						       aborted);
4896f231ddaSDan Williams }
4906f231ddaSDan Williams 
491e301370aSEdmund Nadolski #define isci_request_access_task(req) ((req)->ttype_ptr.io_task_ptr)
4926f231ddaSDan Williams 
493e301370aSEdmund Nadolski #define isci_request_access_tmf(req) ((req)->ttype_ptr.tmf_task_ptr)
4946f231ddaSDan Williams 
495db056250SDan Williams struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost,
4966f231ddaSDan Williams 					       struct isci_tmf *isci_tmf,
497db056250SDan Williams 					       u16 tag);
498209fae14SDan Williams int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev,
499db056250SDan Williams 			 struct sas_task *task, u16 tag);
500ddcc7e34SDan Williams void isci_terminate_pending_requests(struct isci_host *ihost,
501980d3aebSDan Williams 				     struct isci_remote_device *idev);
502e301370aSEdmund Nadolski enum sci_status
503*89a7301fSDan Williams sci_task_request_construct(struct isci_host *ihost,
50478a6f06eSDan Williams 			    struct isci_remote_device *idev,
505f1f52e75SDan Williams 			    u16 io_tag,
5065076a1a9SDan Williams 			    struct isci_request *ireq);
507e301370aSEdmund Nadolski enum sci_status
508*89a7301fSDan Williams sci_task_request_construct_ssp(struct isci_request *ireq);
509e301370aSEdmund Nadolski enum sci_status
510*89a7301fSDan Williams sci_task_request_construct_sata(struct isci_request *ireq);
511e301370aSEdmund Nadolski void
512*89a7301fSDan Williams sci_stp_io_request_set_ncq_tag(struct isci_request *ireq, u16 ncq_tag);
513*89a7301fSDan Williams void sci_smp_request_copy_response(struct isci_request *ireq);
5149274f45eSJeff Skirvin 
5159274f45eSJeff Skirvin static inline int isci_task_is_ncq_recovery(struct sas_task *task)
5169274f45eSJeff Skirvin {
5179274f45eSJeff Skirvin 	return (sas_protocol_ata(task->task_proto) &&
5189274f45eSJeff Skirvin 	        task->ata_task.fis.command == ATA_CMD_READ_LOG_EXT &&
5199274f45eSJeff Skirvin 	        task->ata_task.fis.lbal == ATA_LOG_SATA_NCQ);
5209274f45eSJeff Skirvin 
5219274f45eSJeff Skirvin }
5229274f45eSJeff Skirvin 
5236f231ddaSDan Williams #endif /* !defined(_ISCI_REQUEST_H_) */
524