xref: /openbmc/linux/drivers/scsi/isci/request.h (revision 6f231dda68080759f1aed3769896e94c73099f0f)
1*6f231ddaSDan Williams /*
2*6f231ddaSDan Williams  * This file is provided under a dual BSD/GPLv2 license.  When using or
3*6f231ddaSDan Williams  * redistributing this file, you may do so under either license.
4*6f231ddaSDan Williams  *
5*6f231ddaSDan Williams  * GPL LICENSE SUMMARY
6*6f231ddaSDan Williams  *
7*6f231ddaSDan Williams  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8*6f231ddaSDan Williams  *
9*6f231ddaSDan Williams  * This program is free software; you can redistribute it and/or modify
10*6f231ddaSDan Williams  * it under the terms of version 2 of the GNU General Public License as
11*6f231ddaSDan Williams  * published by the Free Software Foundation.
12*6f231ddaSDan Williams  *
13*6f231ddaSDan Williams  * This program is distributed in the hope that it will be useful, but
14*6f231ddaSDan Williams  * WITHOUT ANY WARRANTY; without even the implied warranty of
15*6f231ddaSDan Williams  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16*6f231ddaSDan Williams  * General Public License for more details.
17*6f231ddaSDan Williams  *
18*6f231ddaSDan Williams  * You should have received a copy of the GNU General Public License
19*6f231ddaSDan Williams  * along with this program; if not, write to the Free Software
20*6f231ddaSDan Williams  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21*6f231ddaSDan Williams  * The full GNU General Public License is included in this distribution
22*6f231ddaSDan Williams  * in the file called LICENSE.GPL.
23*6f231ddaSDan Williams  *
24*6f231ddaSDan Williams  * BSD LICENSE
25*6f231ddaSDan Williams  *
26*6f231ddaSDan Williams  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27*6f231ddaSDan Williams  * All rights reserved.
28*6f231ddaSDan Williams  *
29*6f231ddaSDan Williams  * Redistribution and use in source and binary forms, with or without
30*6f231ddaSDan Williams  * modification, are permitted provided that the following conditions
31*6f231ddaSDan Williams  * are met:
32*6f231ddaSDan Williams  *
33*6f231ddaSDan Williams  *   * Redistributions of source code must retain the above copyright
34*6f231ddaSDan Williams  *     notice, this list of conditions and the following disclaimer.
35*6f231ddaSDan Williams  *   * Redistributions in binary form must reproduce the above copyright
36*6f231ddaSDan Williams  *     notice, this list of conditions and the following disclaimer in
37*6f231ddaSDan Williams  *     the documentation and/or other materials provided with the
38*6f231ddaSDan Williams  *     distribution.
39*6f231ddaSDan Williams  *   * Neither the name of Intel Corporation nor the names of its
40*6f231ddaSDan Williams  *     contributors may be used to endorse or promote products derived
41*6f231ddaSDan Williams  *     from this software without specific prior written permission.
42*6f231ddaSDan Williams  *
43*6f231ddaSDan Williams  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44*6f231ddaSDan Williams  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45*6f231ddaSDan Williams  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46*6f231ddaSDan Williams  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47*6f231ddaSDan Williams  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48*6f231ddaSDan Williams  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49*6f231ddaSDan Williams  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50*6f231ddaSDan Williams  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51*6f231ddaSDan Williams  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52*6f231ddaSDan Williams  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53*6f231ddaSDan Williams  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54*6f231ddaSDan Williams  */
55*6f231ddaSDan Williams 
56*6f231ddaSDan Williams #if !defined(_ISCI_REQUEST_H_)
57*6f231ddaSDan Williams #define _ISCI_REQUEST_H_
58*6f231ddaSDan Williams 
59*6f231ddaSDan Williams #include "isci.h"
60*6f231ddaSDan Williams 
61*6f231ddaSDan Williams /**
62*6f231ddaSDan Williams  * struct isci_request_status - This enum defines the possible states of an I/O
63*6f231ddaSDan Williams  *    request.
64*6f231ddaSDan Williams  *
65*6f231ddaSDan Williams  *
66*6f231ddaSDan Williams  */
67*6f231ddaSDan Williams enum isci_request_status {
68*6f231ddaSDan Williams 	unallocated = 0x00,
69*6f231ddaSDan Williams 	allocated   = 0x01,
70*6f231ddaSDan Williams 	started     = 0x02,
71*6f231ddaSDan Williams 	completed   = 0x03,
72*6f231ddaSDan Williams 	aborting    = 0x04,
73*6f231ddaSDan Williams 	aborted     = 0x05,
74*6f231ddaSDan Williams 	terminating = 0x06
75*6f231ddaSDan Williams };
76*6f231ddaSDan Williams 
77*6f231ddaSDan Williams enum task_type {
78*6f231ddaSDan Williams 	io_task  = 0,
79*6f231ddaSDan Williams 	tmf_task = 1
80*6f231ddaSDan Williams };
81*6f231ddaSDan Williams 
82*6f231ddaSDan Williams /**
83*6f231ddaSDan Williams  * struct isci_request - This class represents the request object used to track
84*6f231ddaSDan Williams  *    IO, smp and TMF request internal. It wraps the SCIC request object.
85*6f231ddaSDan Williams  *
86*6f231ddaSDan Williams  *
87*6f231ddaSDan Williams  */
88*6f231ddaSDan Williams struct isci_request {
89*6f231ddaSDan Williams 
90*6f231ddaSDan Williams 	struct scic_sds_request *sci_request_handle;
91*6f231ddaSDan Williams 
92*6f231ddaSDan Williams 	enum isci_request_status status;
93*6f231ddaSDan Williams 	enum task_type ttype;
94*6f231ddaSDan Williams 	unsigned short io_tag;
95*6f231ddaSDan Williams 	bool complete_in_target;
96*6f231ddaSDan Williams 
97*6f231ddaSDan Williams 	union ttype_ptr_union {
98*6f231ddaSDan Williams 		struct sas_task *io_task_ptr;   /* When ttype==io_task  */
99*6f231ddaSDan Williams 		struct isci_tmf *tmf_task_ptr;  /* When ttype==tmf_task */
100*6f231ddaSDan Williams 	} ttype_ptr;
101*6f231ddaSDan Williams 	struct isci_host *isci_host;
102*6f231ddaSDan Williams 	struct isci_remote_device *isci_device;
103*6f231ddaSDan Williams 	/* For use in the requests_to_{complete|abort} lists: */
104*6f231ddaSDan Williams 	struct list_head completed_node;
105*6f231ddaSDan Williams 	/* For use in the reqs_in_process list: */
106*6f231ddaSDan Williams 	struct list_head dev_node;
107*6f231ddaSDan Williams 	void *sci_request_mem_ptr;
108*6f231ddaSDan Williams 	spinlock_t state_lock;
109*6f231ddaSDan Williams 	dma_addr_t request_daddr;
110*6f231ddaSDan Williams 	dma_addr_t zero_scatter_daddr;
111*6f231ddaSDan Williams 
112*6f231ddaSDan Williams 	unsigned int num_sg_entries;                    /* returned by pci_alloc_sg */
113*6f231ddaSDan Williams 	unsigned int request_alloc_size;                /* size of block from dma_pool_alloc */
114*6f231ddaSDan Williams 
115*6f231ddaSDan Williams 	/** Note: "io_request_completion" is completed in two different ways
116*6f231ddaSDan Williams 	 * depending on whether this is a TMF or regular request.
117*6f231ddaSDan Williams 	 * - TMF requests are completed in the thread that started them;
118*6f231ddaSDan Williams 	 * - regular requests are completed in the request completion callback
119*6f231ddaSDan Williams 	 *   function.
120*6f231ddaSDan Williams 	 * This difference in operation allows the aborter of a TMF request
121*6f231ddaSDan Williams 	 * to be sure that once the TMF request completes, the I/O that the
122*6f231ddaSDan Williams 	 * TMF was aborting is guaranteed to have completed.
123*6f231ddaSDan Williams 	 */
124*6f231ddaSDan Williams 	struct completion *io_request_completion;
125*6f231ddaSDan Williams };
126*6f231ddaSDan Williams 
127*6f231ddaSDan Williams /**
128*6f231ddaSDan Williams  * This function gets the status of the request object.
129*6f231ddaSDan Williams  * @request: This parameter points to the isci_request object
130*6f231ddaSDan Williams  *
131*6f231ddaSDan Williams  * status of the object as a isci_request_status enum.
132*6f231ddaSDan Williams  */
133*6f231ddaSDan Williams static inline
134*6f231ddaSDan Williams enum isci_request_status isci_request_get_state(
135*6f231ddaSDan Williams 	struct isci_request *isci_request)
136*6f231ddaSDan Williams {
137*6f231ddaSDan Williams 	BUG_ON(isci_request == NULL);
138*6f231ddaSDan Williams 
139*6f231ddaSDan Williams 	/*probably a bad sign...	*/
140*6f231ddaSDan Williams 	if (isci_request->status == unallocated)
141*6f231ddaSDan Williams 		dev_warn(&isci_request->isci_host->pdev->dev,
142*6f231ddaSDan Williams 			 "%s: isci_request->status == unallocated\n",
143*6f231ddaSDan Williams 			 __func__);
144*6f231ddaSDan Williams 
145*6f231ddaSDan Williams 	return isci_request->status;
146*6f231ddaSDan Williams }
147*6f231ddaSDan Williams 
148*6f231ddaSDan Williams 
149*6f231ddaSDan Williams /**
150*6f231ddaSDan Williams  * isci_request_change_state() - This function sets the status of the request
151*6f231ddaSDan Williams  *    object.
152*6f231ddaSDan Williams  * @request: This parameter points to the isci_request object
153*6f231ddaSDan Williams  * @status: This Parameter is the new status of the object
154*6f231ddaSDan Williams  *
155*6f231ddaSDan Williams  */
156*6f231ddaSDan Williams static inline enum isci_request_status isci_request_change_state(
157*6f231ddaSDan Williams 	struct isci_request *isci_request,
158*6f231ddaSDan Williams 	enum isci_request_status status)
159*6f231ddaSDan Williams {
160*6f231ddaSDan Williams 	enum isci_request_status old_state;
161*6f231ddaSDan Williams 	unsigned long flags;
162*6f231ddaSDan Williams 
163*6f231ddaSDan Williams 	dev_dbg(&isci_request->isci_host->pdev->dev,
164*6f231ddaSDan Williams 		"%s: isci_request = %p, state = 0x%x\n",
165*6f231ddaSDan Williams 		__func__,
166*6f231ddaSDan Williams 		isci_request,
167*6f231ddaSDan Williams 		status);
168*6f231ddaSDan Williams 
169*6f231ddaSDan Williams 	BUG_ON(isci_request == NULL);
170*6f231ddaSDan Williams 
171*6f231ddaSDan Williams 	spin_lock_irqsave(&isci_request->state_lock, flags);
172*6f231ddaSDan Williams 	old_state = isci_request->status;
173*6f231ddaSDan Williams 	isci_request->status = status;
174*6f231ddaSDan Williams 	spin_unlock_irqrestore(&isci_request->state_lock, flags);
175*6f231ddaSDan Williams 
176*6f231ddaSDan Williams 	return old_state;
177*6f231ddaSDan Williams }
178*6f231ddaSDan Williams 
179*6f231ddaSDan Williams /**
180*6f231ddaSDan Williams  * isci_request_change_started_to_newstate() - This function sets the status of
181*6f231ddaSDan Williams  *    the request object.
182*6f231ddaSDan Williams  * @request: This parameter points to the isci_request object
183*6f231ddaSDan Williams  * @status: This Parameter is the new status of the object
184*6f231ddaSDan Williams  *
185*6f231ddaSDan Williams  * state previous to any change.
186*6f231ddaSDan Williams  */
187*6f231ddaSDan Williams static inline enum isci_request_status isci_request_change_started_to_newstate(
188*6f231ddaSDan Williams 	struct isci_request *isci_request,
189*6f231ddaSDan Williams 	struct completion *completion_ptr,
190*6f231ddaSDan Williams 	enum isci_request_status newstate)
191*6f231ddaSDan Williams {
192*6f231ddaSDan Williams 	enum isci_request_status old_state;
193*6f231ddaSDan Williams 	unsigned long flags;
194*6f231ddaSDan Williams 
195*6f231ddaSDan Williams 	BUG_ON(isci_request == NULL);
196*6f231ddaSDan Williams 
197*6f231ddaSDan Williams 	spin_lock_irqsave(&isci_request->state_lock, flags);
198*6f231ddaSDan Williams 
199*6f231ddaSDan Williams 	old_state = isci_request->status;
200*6f231ddaSDan Williams 
201*6f231ddaSDan Williams 	if (old_state == started) {
202*6f231ddaSDan Williams 		BUG_ON(isci_request->io_request_completion != NULL);
203*6f231ddaSDan Williams 
204*6f231ddaSDan Williams 		isci_request->io_request_completion = completion_ptr;
205*6f231ddaSDan Williams 		isci_request->status = newstate;
206*6f231ddaSDan Williams 	}
207*6f231ddaSDan Williams 	spin_unlock_irqrestore(&isci_request->state_lock, flags);
208*6f231ddaSDan Williams 
209*6f231ddaSDan Williams 	dev_dbg(&isci_request->isci_host->pdev->dev,
210*6f231ddaSDan Williams 		"%s: isci_request = %p, old_state = 0x%x\n",
211*6f231ddaSDan Williams 		__func__,
212*6f231ddaSDan Williams 		isci_request,
213*6f231ddaSDan Williams 		old_state);
214*6f231ddaSDan Williams 
215*6f231ddaSDan Williams 	return old_state;
216*6f231ddaSDan Williams }
217*6f231ddaSDan Williams 
218*6f231ddaSDan Williams /**
219*6f231ddaSDan Williams  * isci_request_change_started_to_aborted() - This function sets the status of
220*6f231ddaSDan Williams  *    the request object.
221*6f231ddaSDan Williams  * @request: This parameter points to the isci_request object
222*6f231ddaSDan Williams  * @completion_ptr: This parameter is saved as the kernel completion structure
223*6f231ddaSDan Williams  *    signalled when the old request completes.
224*6f231ddaSDan Williams  *
225*6f231ddaSDan Williams  * state previous to any change.
226*6f231ddaSDan Williams  */
227*6f231ddaSDan Williams static inline enum isci_request_status isci_request_change_started_to_aborted(
228*6f231ddaSDan Williams 	struct isci_request *isci_request,
229*6f231ddaSDan Williams 	struct completion *completion_ptr)
230*6f231ddaSDan Williams {
231*6f231ddaSDan Williams 	return isci_request_change_started_to_newstate(
232*6f231ddaSDan Williams 		       isci_request, completion_ptr, aborted
233*6f231ddaSDan Williams 		       );
234*6f231ddaSDan Williams }
235*6f231ddaSDan Williams /**
236*6f231ddaSDan Williams  * isci_request_free() - This function frees the request object.
237*6f231ddaSDan Williams  * @isci_host: This parameter specifies the ISCI host object
238*6f231ddaSDan Williams  * @isci_request: This parameter points to the isci_request object
239*6f231ddaSDan Williams  *
240*6f231ddaSDan Williams  */
241*6f231ddaSDan Williams static inline void isci_request_free(
242*6f231ddaSDan Williams 	struct isci_host *isci_host,
243*6f231ddaSDan Williams 	struct isci_request *isci_request)
244*6f231ddaSDan Williams {
245*6f231ddaSDan Williams 	BUG_ON(isci_request == NULL);
246*6f231ddaSDan Williams 
247*6f231ddaSDan Williams 	/* release the dma memory if we fail. */
248*6f231ddaSDan Williams 	dma_pool_free(isci_host->dma_pool, isci_request,
249*6f231ddaSDan Williams 		      isci_request->request_daddr);
250*6f231ddaSDan Williams }
251*6f231ddaSDan Williams 
252*6f231ddaSDan Williams 
253*6f231ddaSDan Williams /* #define ISCI_REQUEST_VALIDATE_ACCESS
254*6f231ddaSDan Williams  */
255*6f231ddaSDan Williams 
256*6f231ddaSDan Williams #ifdef ISCI_REQUEST_VALIDATE_ACCESS
257*6f231ddaSDan Williams 
258*6f231ddaSDan Williams static inline
259*6f231ddaSDan Williams struct sas_task *isci_request_access_task(struct isci_request *isci_request)
260*6f231ddaSDan Williams {
261*6f231ddaSDan Williams 	BUG_ON(isci_request->ttype != io_task);
262*6f231ddaSDan Williams 	return isci_request->ttype_ptr.io_task_ptr;
263*6f231ddaSDan Williams }
264*6f231ddaSDan Williams 
265*6f231ddaSDan Williams static inline
266*6f231ddaSDan Williams struct isci_tmf *isci_request_access_tmf(struct isci_request *isci_request)
267*6f231ddaSDan Williams {
268*6f231ddaSDan Williams 	BUG_ON(isci_request->ttype != tmf_task);
269*6f231ddaSDan Williams 	return isci_request->ttype_ptr.tmf_task_ptr;
270*6f231ddaSDan Williams }
271*6f231ddaSDan Williams 
272*6f231ddaSDan Williams #else  /* not ISCI_REQUEST_VALIDATE_ACCESS */
273*6f231ddaSDan Williams 
274*6f231ddaSDan Williams #define isci_request_access_task(RequestPtr) \
275*6f231ddaSDan Williams 	((RequestPtr)->ttype_ptr.io_task_ptr)
276*6f231ddaSDan Williams 
277*6f231ddaSDan Williams #define isci_request_access_tmf(RequestPtr)  \
278*6f231ddaSDan Williams 	((RequestPtr)->ttype_ptr.tmf_task_ptr)
279*6f231ddaSDan Williams 
280*6f231ddaSDan Williams #endif /* not ISCI_REQUEST_VALIDATE_ACCESS */
281*6f231ddaSDan Williams 
282*6f231ddaSDan Williams 
283*6f231ddaSDan Williams int isci_request_alloc_tmf(
284*6f231ddaSDan Williams 	struct isci_host *isci_host,
285*6f231ddaSDan Williams 	struct isci_tmf *isci_tmf,
286*6f231ddaSDan Williams 	struct isci_request **isci_request,
287*6f231ddaSDan Williams 	struct isci_remote_device *isci_device,
288*6f231ddaSDan Williams 	gfp_t gfp_flags);
289*6f231ddaSDan Williams 
290*6f231ddaSDan Williams 
291*6f231ddaSDan Williams int isci_request_execute(
292*6f231ddaSDan Williams 	struct isci_host *isci_host,
293*6f231ddaSDan Williams 	struct sas_task *task,
294*6f231ddaSDan Williams 	struct isci_request **request,
295*6f231ddaSDan Williams 	gfp_t gfp_flags);
296*6f231ddaSDan Williams 
297*6f231ddaSDan Williams /**
298*6f231ddaSDan Williams  * isci_request_unmap_sgl() - This function unmaps the DMA address of a given
299*6f231ddaSDan Williams  *    sgl
300*6f231ddaSDan Williams  * @request: This parameter points to the isci_request object
301*6f231ddaSDan Williams  * @*pdev: This Parameter is the pci_device struct for the controller
302*6f231ddaSDan Williams  *
303*6f231ddaSDan Williams  */
304*6f231ddaSDan Williams static inline void isci_request_unmap_sgl(
305*6f231ddaSDan Williams 	struct isci_request *request,
306*6f231ddaSDan Williams 	struct pci_dev *pdev)
307*6f231ddaSDan Williams {
308*6f231ddaSDan Williams 	struct sas_task *task = isci_request_access_task(request);
309*6f231ddaSDan Williams 
310*6f231ddaSDan Williams 	dev_dbg(&request->isci_host->pdev->dev,
311*6f231ddaSDan Williams 		"%s: request = %p, task = %p,\n"
312*6f231ddaSDan Williams 		"task->data_dir = %d, is_sata = %d\n ",
313*6f231ddaSDan Williams 		__func__,
314*6f231ddaSDan Williams 		request,
315*6f231ddaSDan Williams 		task,
316*6f231ddaSDan Williams 		task->data_dir,
317*6f231ddaSDan Williams 		sas_protocol_ata(task->task_proto));
318*6f231ddaSDan Williams 
319*6f231ddaSDan Williams 	if ((task->data_dir != PCI_DMA_NONE) &&
320*6f231ddaSDan Williams 	    !sas_protocol_ata(task->task_proto)) {
321*6f231ddaSDan Williams 		if (task->num_scatter == 0)
322*6f231ddaSDan Williams 			/* 0 indicates a single dma address */
323*6f231ddaSDan Williams 			dma_unmap_single(
324*6f231ddaSDan Williams 				&pdev->dev,
325*6f231ddaSDan Williams 				request->zero_scatter_daddr,
326*6f231ddaSDan Williams 				task->total_xfer_len,
327*6f231ddaSDan Williams 				task->data_dir
328*6f231ddaSDan Williams 				);
329*6f231ddaSDan Williams 
330*6f231ddaSDan Williams 		else  /* unmap the sgl dma addresses */
331*6f231ddaSDan Williams 			dma_unmap_sg(
332*6f231ddaSDan Williams 				&pdev->dev,
333*6f231ddaSDan Williams 				task->scatter,
334*6f231ddaSDan Williams 				request->num_sg_entries,
335*6f231ddaSDan Williams 				task->data_dir
336*6f231ddaSDan Williams 				);
337*6f231ddaSDan Williams 	}
338*6f231ddaSDan Williams }
339*6f231ddaSDan Williams 
340*6f231ddaSDan Williams 
341*6f231ddaSDan Williams void isci_request_io_request_complete(
342*6f231ddaSDan Williams 	struct isci_host *isci_host,
343*6f231ddaSDan Williams 	struct isci_request *request,
344*6f231ddaSDan Williams 	enum sci_io_status completion_status);
345*6f231ddaSDan Williams 
346*6f231ddaSDan Williams u32 isci_request_io_request_get_transfer_length(
347*6f231ddaSDan Williams 	struct isci_request *request);
348*6f231ddaSDan Williams 
349*6f231ddaSDan Williams SCI_IO_REQUEST_DATA_DIRECTION isci_request_io_request_get_data_direction(
350*6f231ddaSDan Williams 	struct isci_request *request);
351*6f231ddaSDan Williams 
352*6f231ddaSDan Williams /**
353*6f231ddaSDan Williams  * isci_request_io_request_get_next_sge() - This function is called by the sci
354*6f231ddaSDan Williams  *    core to retrieve the next sge for a given request.
355*6f231ddaSDan Williams  * @request: This parameter is the isci_request object.
356*6f231ddaSDan Williams  * @current_sge_address: This parameter is the last sge retrieved by the sci
357*6f231ddaSDan Williams  *    core for this request.
358*6f231ddaSDan Williams  *
359*6f231ddaSDan Williams  * pointer to the next sge for specified request.
360*6f231ddaSDan Williams  */
361*6f231ddaSDan Williams static inline void *isci_request_io_request_get_next_sge(
362*6f231ddaSDan Williams 	struct isci_request *request,
363*6f231ddaSDan Williams 	void *current_sge_address)
364*6f231ddaSDan Williams {
365*6f231ddaSDan Williams 	struct sas_task *task = isci_request_access_task(request);
366*6f231ddaSDan Williams 	void *ret = NULL;
367*6f231ddaSDan Williams 
368*6f231ddaSDan Williams 	dev_dbg(&request->isci_host->pdev->dev,
369*6f231ddaSDan Williams 		"%s: request = %p, "
370*6f231ddaSDan Williams 		"current_sge_address = %p, "
371*6f231ddaSDan Williams 		"num_scatter = %d\n",
372*6f231ddaSDan Williams 		__func__,
373*6f231ddaSDan Williams 		request,
374*6f231ddaSDan Williams 		current_sge_address,
375*6f231ddaSDan Williams 		task->num_scatter);
376*6f231ddaSDan Williams 
377*6f231ddaSDan Williams 	if (!current_sge_address)	/* First time through.. */
378*6f231ddaSDan Williams 		ret = task->scatter;    /* always task->scatter */
379*6f231ddaSDan Williams 	else if (task->num_scatter == 0) /* Next element, if num_scatter == 0 */
380*6f231ddaSDan Williams 		ret = NULL;              /* there is only one element. */
381*6f231ddaSDan Williams 	else
382*6f231ddaSDan Williams 		ret = sg_next(current_sge_address);     /* sg_next returns NULL
383*6f231ddaSDan Williams 							 * for the last element
384*6f231ddaSDan Williams 							 */
385*6f231ddaSDan Williams 
386*6f231ddaSDan Williams 	dev_dbg(&request->isci_host->pdev->dev,
387*6f231ddaSDan Williams 		"%s: next sge address = %p\n",
388*6f231ddaSDan Williams 		__func__,
389*6f231ddaSDan Williams 		ret);
390*6f231ddaSDan Williams 
391*6f231ddaSDan Williams 	return ret;
392*6f231ddaSDan Williams }
393*6f231ddaSDan Williams 
394*6f231ddaSDan Williams dma_addr_t isci_request_sge_get_address_field(
395*6f231ddaSDan Williams 	struct isci_request *request,
396*6f231ddaSDan Williams 	void *sge_address);
397*6f231ddaSDan Williams 
398*6f231ddaSDan Williams u32 isci_request_sge_get_length_field(
399*6f231ddaSDan Williams 	struct isci_request *request,
400*6f231ddaSDan Williams 	void *sge_address);
401*6f231ddaSDan Williams 
402*6f231ddaSDan Williams void *isci_request_ssp_io_request_get_cdb_address(
403*6f231ddaSDan Williams 	struct isci_request *request);
404*6f231ddaSDan Williams 
405*6f231ddaSDan Williams u32 isci_request_ssp_io_request_get_cdb_length(
406*6f231ddaSDan Williams 	struct isci_request *request);
407*6f231ddaSDan Williams 
408*6f231ddaSDan Williams u32  isci_request_ssp_io_request_get_lun(
409*6f231ddaSDan Williams 	struct isci_request *request);
410*6f231ddaSDan Williams 
411*6f231ddaSDan Williams u32 isci_request_ssp_io_request_get_task_attribute(
412*6f231ddaSDan Williams 	struct isci_request *request);
413*6f231ddaSDan Williams 
414*6f231ddaSDan Williams u32 isci_request_ssp_io_request_get_command_priority(
415*6f231ddaSDan Williams 	struct isci_request *request);
416*6f231ddaSDan Williams 
417*6f231ddaSDan Williams 
418*6f231ddaSDan Williams 
419*6f231ddaSDan Williams 
420*6f231ddaSDan Williams 
421*6f231ddaSDan Williams void isci_terminate_pending_requests(
422*6f231ddaSDan Williams 	struct isci_host *isci_host,
423*6f231ddaSDan Williams 	struct isci_remote_device *isci_device,
424*6f231ddaSDan Williams 	enum isci_request_status new_request_state);
425*6f231ddaSDan Williams 
426*6f231ddaSDan Williams 
427*6f231ddaSDan Williams 
428*6f231ddaSDan Williams 
429*6f231ddaSDan Williams #endif /* !defined(_ISCI_REQUEST_H_) */
430