xref: /openbmc/linux/drivers/scsi/isci/host.h (revision e2f8db50)
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  */
55ce2b3261SDan Williams #ifndef _SCI_HOST_H_
566f231ddaSDan Williams #define _SCI_HOST_H_
576f231ddaSDan Williams 
586f231ddaSDan Williams #include "remote_device.h"
59ce2b3261SDan Williams #include "phy.h"
60cc9203bfSDan Williams #include "pool.h"
613bff9d54SDan Williams #include "state_machine.h"
62cc9203bfSDan Williams #include "remote_node_table.h"
6363a3a15fSDan Williams #include "registers.h"
64cc9203bfSDan Williams #include "scu_unsolicited_frame.h"
6563a3a15fSDan Williams #include "unsolicited_frame_control.h"
66e2f8db50SDan Williams #include "probe_roms.h"
67cc9203bfSDan Williams 
68cc9203bfSDan Williams struct scic_sds_request;
69cc9203bfSDan Williams struct scu_task_context;
70cc9203bfSDan Williams 
71e2f8db50SDan Williams 
72cc9203bfSDan Williams /**
73cc9203bfSDan Williams  * struct scic_power_control -
74cc9203bfSDan Williams  *
75cc9203bfSDan Williams  * This structure defines the fields for managing power control for direct
76cc9203bfSDan Williams  * attached disk devices.
77cc9203bfSDan Williams  */
78cc9203bfSDan Williams struct scic_power_control {
79cc9203bfSDan Williams 	/**
80cc9203bfSDan Williams 	 * This field is set when the power control timer is running and cleared when
81cc9203bfSDan Williams 	 * it is not.
82cc9203bfSDan Williams 	 */
83cc9203bfSDan Williams 	bool timer_started;
84cc9203bfSDan Williams 
85cc9203bfSDan Williams 	/**
86cc9203bfSDan Williams 	 * This field is the handle to the driver timer object.  This timer is used to
87cc9203bfSDan Williams 	 * control when the directed attached disks can consume power.
88cc9203bfSDan Williams 	 */
89cc9203bfSDan Williams 	void *timer;
90cc9203bfSDan Williams 
91cc9203bfSDan Williams 	/**
92cc9203bfSDan Williams 	 * This field is used to keep track of how many phys are put into the
93cc9203bfSDan Williams 	 * requesters field.
94cc9203bfSDan Williams 	 */
95cc9203bfSDan Williams 	u8 phys_waiting;
96cc9203bfSDan Williams 
97cc9203bfSDan Williams 	/**
98cc9203bfSDan Williams 	 * This field is used to keep track of how many phys have been granted to consume power
99cc9203bfSDan Williams 	 */
100cc9203bfSDan Williams 	u8 phys_granted_power;
101cc9203bfSDan Williams 
102cc9203bfSDan Williams 	/**
103cc9203bfSDan Williams 	 * This field is an array of phys that we are waiting on. The phys are direct
104cc9203bfSDan Williams 	 * mapped into requesters via struct scic_sds_phy.phy_index
105cc9203bfSDan Williams 	 */
106cc9203bfSDan Williams 	struct scic_sds_phy *requesters[SCI_MAX_PHYS];
107cc9203bfSDan Williams 
108cc9203bfSDan Williams };
109cc9203bfSDan Williams 
110e2f8db50SDan Williams struct scic_sds_port_configuration_agent;
111e2f8db50SDan Williams typedef void (*port_config_fn)(struct scic_sds_controller *,
112e2f8db50SDan Williams 			       struct scic_sds_port_configuration_agent *,
113e2f8db50SDan Williams 			       struct scic_sds_port *, struct scic_sds_phy *);
114e2f8db50SDan Williams 
115e2f8db50SDan Williams struct scic_sds_port_configuration_agent {
116e2f8db50SDan Williams 	u16 phy_configured_mask;
117e2f8db50SDan Williams 	u16 phy_ready_mask;
118e2f8db50SDan Williams 	struct {
119e2f8db50SDan Williams 		u8 min_index;
120e2f8db50SDan Williams 		u8 max_index;
121e2f8db50SDan Williams 	} phy_valid_port_range[SCI_MAX_PHYS];
122e2f8db50SDan Williams 	bool timer_pending;
123e2f8db50SDan Williams 	port_config_fn link_up_handler;
124e2f8db50SDan Williams 	port_config_fn link_down_handler;
125e2f8db50SDan Williams 	void *timer;
126e2f8db50SDan Williams };
127e2f8db50SDan Williams 
128cc9203bfSDan Williams /**
129cc9203bfSDan Williams  * struct scic_sds_controller -
130cc9203bfSDan Williams  *
131cc9203bfSDan Williams  * This structure represents the SCU controller object.
132cc9203bfSDan Williams  */
133cc9203bfSDan Williams struct scic_sds_controller {
134cc9203bfSDan Williams 	/**
135cc9203bfSDan Williams 	 * This field contains the information for the base controller state
136cc9203bfSDan Williams 	 * machine.
137cc9203bfSDan Williams 	 */
138cc9203bfSDan Williams 	struct sci_base_state_machine state_machine;
139cc9203bfSDan Williams 
140cc9203bfSDan Williams 	/**
141cc9203bfSDan Williams 	 * This field is the driver timer object handler used to time the controller
142cc9203bfSDan Williams 	 * object start and stop requests.
143cc9203bfSDan Williams 	 */
144cc9203bfSDan Williams 	void *timeout_timer;
145cc9203bfSDan Williams 
146cc9203bfSDan Williams 	/**
147cc9203bfSDan Williams 	 * This field contains the user parameters to be utilized for this
148cc9203bfSDan Williams 	 * core controller object.
149cc9203bfSDan Williams 	 */
150cc9203bfSDan Williams 	union scic_user_parameters user_parameters;
151cc9203bfSDan Williams 
152cc9203bfSDan Williams 	/**
153cc9203bfSDan Williams 	 * This field contains the OEM parameters to be utilized for this
154cc9203bfSDan Williams 	 * core controller object.
155cc9203bfSDan Williams 	 */
156cc9203bfSDan Williams 	union scic_oem_parameters oem_parameters;
157cc9203bfSDan Williams 
158cc9203bfSDan Williams 	/**
159cc9203bfSDan Williams 	 * This field contains the port configuration agent for this controller.
160cc9203bfSDan Williams 	 */
161cc9203bfSDan Williams 	struct scic_sds_port_configuration_agent port_agent;
162cc9203bfSDan Williams 
163cc9203bfSDan Williams 	/**
164cc9203bfSDan Williams 	 * This field is the array of device objects that are currently constructed
165cc9203bfSDan Williams 	 * for this controller object.  This table is used as a fast lookup of device
166cc9203bfSDan Williams 	 * objects that need to handle device completion notifications from the
167cc9203bfSDan Williams 	 * hardware. The table is RNi based.
168cc9203bfSDan Williams 	 */
169cc9203bfSDan Williams 	struct scic_sds_remote_device *device_table[SCI_MAX_REMOTE_DEVICES];
170cc9203bfSDan Williams 
171cc9203bfSDan Williams 	/**
172cc9203bfSDan Williams 	 * This field is the array of IO request objects that are currently active for
173cc9203bfSDan Williams 	 * this controller object.  This table is used as a fast lookup of the io
174cc9203bfSDan Williams 	 * request object that need to handle completion queue notifications.  The
175cc9203bfSDan Williams 	 * table is TCi based.
176cc9203bfSDan Williams 	 */
177cc9203bfSDan Williams 	struct scic_sds_request *io_request_table[SCI_MAX_IO_REQUESTS];
178cc9203bfSDan Williams 
179cc9203bfSDan Williams 	/**
180cc9203bfSDan Williams 	 * This field is the free RNi data structure
181cc9203bfSDan Williams 	 */
182cc9203bfSDan Williams 	struct scic_remote_node_table available_remote_nodes;
183cc9203bfSDan Williams 
184cc9203bfSDan Williams 	/**
185cc9203bfSDan Williams 	 * This field is the TCi pool used to manage the task context index.
186cc9203bfSDan Williams 	 */
187cc9203bfSDan Williams 	SCI_POOL_CREATE(tci_pool, u16, SCI_MAX_IO_REQUESTS);
188cc9203bfSDan Williams 
189cc9203bfSDan Williams 	/**
190cc9203bfSDan Williams 	 * This filed is the struct scic_power_control data used to controll when direct
191cc9203bfSDan Williams 	 * attached devices can consume power.
192cc9203bfSDan Williams 	 */
193cc9203bfSDan Williams 	struct scic_power_control power_control;
194cc9203bfSDan Williams 
195cc9203bfSDan Williams 	/**
196cc9203bfSDan Williams 	 * This field is the array of sequence values for the IO Tag fields.  Even
197cc9203bfSDan Williams 	 * though only 4 bits of the field is used for the sequence the sequence is 16
198cc9203bfSDan Williams 	 * bits in size so the sequence can be bitwise or'd with the TCi to build the
199cc9203bfSDan Williams 	 * IO Tag value.
200cc9203bfSDan Williams 	 */
201cc9203bfSDan Williams 	u16 io_request_sequence[SCI_MAX_IO_REQUESTS];
202cc9203bfSDan Williams 
203cc9203bfSDan Williams 	/**
204cc9203bfSDan Williams 	 * This field in the array of sequence values for the RNi.  These are used
205cc9203bfSDan Williams 	 * to control io request build to io request start operations.  The sequence
206cc9203bfSDan Williams 	 * value is recorded into an io request when it is built and is checked on
207cc9203bfSDan Williams 	 * the io request start operation to make sure that there was not a device
208cc9203bfSDan Williams 	 * hot plug between the build and start operation.
209cc9203bfSDan Williams 	 */
210cc9203bfSDan Williams 	u8 remote_device_sequence[SCI_MAX_REMOTE_DEVICES];
211cc9203bfSDan Williams 
212cc9203bfSDan Williams 	/**
213cc9203bfSDan Williams 	 * This field is a pointer to the memory allocated by the driver for the task
214cc9203bfSDan Williams 	 * context table.  This data is shared between the hardware and software.
215cc9203bfSDan Williams 	 */
216cc9203bfSDan Williams 	struct scu_task_context *task_context_table;
217cc9203bfSDan Williams 
218cc9203bfSDan Williams 	/**
219cc9203bfSDan Williams 	 * This field is a pointer to the memory allocated by the driver for the
220cc9203bfSDan Williams 	 * remote node context table.  This table is shared between the hardware and
221cc9203bfSDan Williams 	 * software.
222cc9203bfSDan Williams 	 */
223cc9203bfSDan Williams 	union scu_remote_node_context *remote_node_context_table;
224cc9203bfSDan Williams 
225cc9203bfSDan Williams 	/**
226cc9203bfSDan Williams 	 * This field is a pointer to the completion queue.  This memory is
227cc9203bfSDan Williams 	 * written to by the hardware and read by the software.
228cc9203bfSDan Williams 	 */
229cc9203bfSDan Williams 	u32 *completion_queue;
230cc9203bfSDan Williams 
231cc9203bfSDan Williams 	/**
232cc9203bfSDan Williams 	 * This field is the software copy of the completion queue get pointer.  The
233cc9203bfSDan Williams 	 * controller object writes this value to the hardware after processing the
234cc9203bfSDan Williams 	 * completion entries.
235cc9203bfSDan Williams 	 */
236cc9203bfSDan Williams 	u32 completion_queue_get;
237cc9203bfSDan Williams 
238cc9203bfSDan Williams 	/**
239cc9203bfSDan Williams 	 * This field is the minimum of the number of hardware supported port entries
240cc9203bfSDan Williams 	 * and the software requested port entries.
241cc9203bfSDan Williams 	 */
242cc9203bfSDan Williams 	u32 logical_port_entries;
243cc9203bfSDan Williams 
244cc9203bfSDan Williams 	/**
245cc9203bfSDan Williams 	 * This field is the minimum number of hardware supported completion queue
246cc9203bfSDan Williams 	 * entries and the software requested completion queue entries.
247cc9203bfSDan Williams 	 */
248cc9203bfSDan Williams 	u32 completion_queue_entries;
249cc9203bfSDan Williams 
250cc9203bfSDan Williams 	/**
251cc9203bfSDan Williams 	 * This field is the minimum number of hardware supported event entries and
252cc9203bfSDan Williams 	 * the software requested event entries.
253cc9203bfSDan Williams 	 */
254cc9203bfSDan Williams 	u32 completion_event_entries;
255cc9203bfSDan Williams 
256cc9203bfSDan Williams 	/**
257cc9203bfSDan Williams 	 * This field is the minimum number of devices supported by the hardware and
258cc9203bfSDan Williams 	 * the number of devices requested by the software.
259cc9203bfSDan Williams 	 */
260cc9203bfSDan Williams 	u32 remote_node_entries;
261cc9203bfSDan Williams 
262cc9203bfSDan Williams 	/**
263cc9203bfSDan Williams 	 * This field is the minimum number of IO requests supported by the hardware
264cc9203bfSDan Williams 	 * and the number of IO requests requested by the software.
265cc9203bfSDan Williams 	 */
266cc9203bfSDan Williams 	u32 task_context_entries;
267cc9203bfSDan Williams 
268cc9203bfSDan Williams 	/**
269cc9203bfSDan Williams 	 * This object contains all of the unsolicited frame specific
270cc9203bfSDan Williams 	 * data utilized by the core controller.
271cc9203bfSDan Williams 	 */
272cc9203bfSDan Williams 	struct scic_sds_unsolicited_frame_control uf_control;
273cc9203bfSDan Williams 
274cc9203bfSDan Williams 	/* Phy Startup Data */
275cc9203bfSDan Williams 	/**
276cc9203bfSDan Williams 	 * This field is the driver timer handle for controller phy request startup.
277cc9203bfSDan Williams 	 * On controller start the controller will start each PHY individually in
278cc9203bfSDan Williams 	 * order of phy index.
279cc9203bfSDan Williams 	 */
280cc9203bfSDan Williams 	void *phy_startup_timer;
281cc9203bfSDan Williams 
282cc9203bfSDan Williams 	/**
283cc9203bfSDan Williams 	 * This field is set when the phy_startup_timer is running and is cleared when
284cc9203bfSDan Williams 	 * the phy_startup_timer is stopped.
285cc9203bfSDan Williams 	 */
286cc9203bfSDan Williams 	bool phy_startup_timer_pending;
287cc9203bfSDan Williams 
288cc9203bfSDan Williams 	/**
289cc9203bfSDan Williams 	 * This field is the index of the next phy start.  It is initialized to 0 and
290cc9203bfSDan Williams 	 * increments for each phy index that is started.
291cc9203bfSDan Williams 	 */
292cc9203bfSDan Williams 	u32 next_phy_to_start;
293cc9203bfSDan Williams 
294cc9203bfSDan Williams 	/**
295cc9203bfSDan Williams 	 * This field controlls the invalid link up notifications to the SCI_USER.  If
296cc9203bfSDan Williams 	 * an invalid_link_up notification is reported a bit for the PHY index is set
297cc9203bfSDan Williams 	 * so further notifications are not made.  Once the PHY object reports link up
298cc9203bfSDan Williams 	 * and is made part of a port then this bit for the PHY index is cleared.
299cc9203bfSDan Williams 	 */
300cc9203bfSDan Williams 	u8 invalid_phy_mask;
301cc9203bfSDan Williams 
302cc9203bfSDan Williams 	/*
303cc9203bfSDan Williams 	 * This field saves the current interrupt coalescing number of the controller.
304cc9203bfSDan Williams 	 */
305cc9203bfSDan Williams 	u16 interrupt_coalesce_number;
306cc9203bfSDan Williams 
307cc9203bfSDan Williams 	/*
308cc9203bfSDan Williams 	 * This field saves the current interrupt coalescing timeout value in microseconds.
309cc9203bfSDan Williams 	 */
310cc9203bfSDan Williams 	u32 interrupt_coalesce_timeout;
311cc9203bfSDan Williams 
312cc9203bfSDan Williams 	/**
313cc9203bfSDan Williams 	 * This field is a pointer to the memory mapped register space for the
314cc9203bfSDan Williams 	 * struct smu_registers.
315cc9203bfSDan Williams 	 */
316cc9203bfSDan Williams 	struct smu_registers __iomem *smu_registers;
317cc9203bfSDan Williams 
318cc9203bfSDan Williams 	/**
319cc9203bfSDan Williams 	 * This field is a pointer to the memory mapped register space for the
320cc9203bfSDan Williams 	 * struct scu_registers.
321cc9203bfSDan Williams 	 */
322cc9203bfSDan Williams 	struct scu_registers __iomem *scu_registers;
323cc9203bfSDan Williams 
324cc9203bfSDan Williams };
3256f231ddaSDan Williams 
3266f231ddaSDan Williams struct isci_host {
327cc3dbd0aSArtur Wojcik 	struct scic_sds_controller sci;
3286f231ddaSDan Williams 	union scic_oem_parameters oem_parameters;
3296f231ddaSDan Williams 
3306f231ddaSDan Williams 	int id; /* unique within a given pci device */
3317c40a803SDan Williams 	struct list_head timers;
3326f231ddaSDan Williams 	void *core_ctrl_memory;
3336f231ddaSDan Williams 	struct dma_pool *dma_pool;
3346f231ddaSDan Williams 	struct isci_phy phys[SCI_MAX_PHYS];
335e531381eSDan Williams 	struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */
3366f231ddaSDan Williams 	struct sas_ha_struct sas_ha;
3376f231ddaSDan Williams 
3386f231ddaSDan Williams 	int can_queue;
3396f231ddaSDan Williams 	spinlock_t queue_lock;
3406f231ddaSDan Williams 	spinlock_t state_lock;
3416f231ddaSDan Williams 
3426f231ddaSDan Williams 	struct pci_dev *pdev;
3436f231ddaSDan Williams 
3446f231ddaSDan Williams 	enum isci_status status;
3450cf89d1dSDan Williams 	#define IHOST_START_PENDING 0
3460cf89d1dSDan Williams 	#define IHOST_STOP_PENDING 1
3470cf89d1dSDan Williams 	unsigned long flags;
3480cf89d1dSDan Williams 	wait_queue_head_t eventq;
3496f231ddaSDan Williams 	struct Scsi_Host *shost;
3506f231ddaSDan Williams 	struct tasklet_struct completion_tasklet;
3516f231ddaSDan Williams 	struct list_head requests_to_complete;
35211b00c19SJeff Skirvin 	struct list_head requests_to_errorback;
3536f231ddaSDan Williams 	spinlock_t scic_lock;
354d9c37390SDan Williams 
35557f20f4eSDan Williams 	struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES];
3566f231ddaSDan Williams };
3576f231ddaSDan Williams 
3586f231ddaSDan Williams /**
359cc9203bfSDan Williams  * enum scic_sds_controller_states - This enumeration depicts all the states
360cc9203bfSDan Williams  *    for the common controller state machine.
361cc9203bfSDan Williams  */
362cc9203bfSDan Williams enum scic_sds_controller_states {
363cc9203bfSDan Williams 	/**
364cc9203bfSDan Williams 	 * Simply the initial state for the base controller state machine.
365cc9203bfSDan Williams 	 */
366cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_STATE_INITIAL = 0,
367cc9203bfSDan Williams 
368cc9203bfSDan Williams 	/**
369cc9203bfSDan Williams 	 * This state indicates that the controller is reset.  The memory for
370cc9203bfSDan Williams 	 * the controller is in it's initial state, but the controller requires
371cc9203bfSDan Williams 	 * initialization.
372cc9203bfSDan Williams 	 * This state is entered from the INITIAL state.
373cc9203bfSDan Williams 	 * This state is entered from the RESETTING state.
374cc9203bfSDan Williams 	 */
375cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_STATE_RESET,
376cc9203bfSDan Williams 
377cc9203bfSDan Williams 	/**
378cc9203bfSDan Williams 	 * This state is typically an action state that indicates the controller
379cc9203bfSDan Williams 	 * is in the process of initialization.  In this state no new IO operations
380cc9203bfSDan Williams 	 * are permitted.
381cc9203bfSDan Williams 	 * This state is entered from the RESET state.
382cc9203bfSDan Williams 	 */
383cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_STATE_INITIALIZING,
384cc9203bfSDan Williams 
385cc9203bfSDan Williams 	/**
386cc9203bfSDan Williams 	 * This state indicates that the controller has been successfully
387cc9203bfSDan Williams 	 * initialized.  In this state no new IO operations are permitted.
388cc9203bfSDan Williams 	 * This state is entered from the INITIALIZING state.
389cc9203bfSDan Williams 	 */
390cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_STATE_INITIALIZED,
391cc9203bfSDan Williams 
392cc9203bfSDan Williams 	/**
393cc9203bfSDan Williams 	 * This state indicates the the controller is in the process of becoming
394cc9203bfSDan Williams 	 * ready (i.e. starting).  In this state no new IO operations are permitted.
395cc9203bfSDan Williams 	 * This state is entered from the INITIALIZED state.
396cc9203bfSDan Williams 	 */
397cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_STATE_STARTING,
398cc9203bfSDan Williams 
399cc9203bfSDan Williams 	/**
400cc9203bfSDan Williams 	 * This state indicates the controller is now ready.  Thus, the user
401cc9203bfSDan Williams 	 * is able to perform IO operations on the controller.
402cc9203bfSDan Williams 	 * This state is entered from the STARTING state.
403cc9203bfSDan Williams 	 */
404cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_STATE_READY,
405cc9203bfSDan Williams 
406cc9203bfSDan Williams 	/**
407cc9203bfSDan Williams 	 * This state is typically an action state that indicates the controller
408cc9203bfSDan Williams 	 * is in the process of resetting.  Thus, the user is unable to perform
409cc9203bfSDan Williams 	 * IO operations on the controller.  A reset is considered destructive in
410cc9203bfSDan Williams 	 * most cases.
411cc9203bfSDan Williams 	 * This state is entered from the READY state.
412cc9203bfSDan Williams 	 * This state is entered from the FAILED state.
413cc9203bfSDan Williams 	 * This state is entered from the STOPPED state.
414cc9203bfSDan Williams 	 */
415cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_STATE_RESETTING,
416cc9203bfSDan Williams 
417cc9203bfSDan Williams 	/**
418cc9203bfSDan Williams 	 * This state indicates that the controller is in the process of stopping.
419cc9203bfSDan Williams 	 * In this state no new IO operations are permitted, but existing IO
420cc9203bfSDan Williams 	 * operations are allowed to complete.
421cc9203bfSDan Williams 	 * This state is entered from the READY state.
422cc9203bfSDan Williams 	 */
423cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_STATE_STOPPING,
424cc9203bfSDan Williams 
425cc9203bfSDan Williams 	/**
426cc9203bfSDan Williams 	 * This state indicates that the controller has successfully been stopped.
427cc9203bfSDan Williams 	 * In this state no new IO operations are permitted.
428cc9203bfSDan Williams 	 * This state is entered from the STOPPING state.
429cc9203bfSDan Williams 	 */
430cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_STATE_STOPPED,
431cc9203bfSDan Williams 
432cc9203bfSDan Williams 	/**
433cc9203bfSDan Williams 	 * This state indicates that the controller could not successfully be
434cc9203bfSDan Williams 	 * initialized.  In this state no new IO operations are permitted.
435cc9203bfSDan Williams 	 * This state is entered from the INITIALIZING state.
436cc9203bfSDan Williams 	 * This state is entered from the STARTING state.
437cc9203bfSDan Williams 	 * This state is entered from the STOPPING state.
438cc9203bfSDan Williams 	 * This state is entered from the RESETTING state.
439cc9203bfSDan Williams 	 */
440cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_STATE_FAILED,
441cc9203bfSDan Williams 
442cc9203bfSDan Williams 	SCI_BASE_CONTROLLER_MAX_STATES
443cc9203bfSDan Williams 
444cc9203bfSDan Williams };
445cc9203bfSDan Williams 
446cc9203bfSDan Williams 
447cc9203bfSDan Williams 
448cc9203bfSDan Williams /**
4496f231ddaSDan Williams  * struct isci_pci_info - This class represents the pci function containing the
4506f231ddaSDan Williams  *    controllers. Depending on PCI SKU, there could be up to 2 controllers in
4516f231ddaSDan Williams  *    the PCI function.
4526f231ddaSDan Williams  */
4536f231ddaSDan Williams #define SCI_MAX_MSIX_INT (SCI_NUM_MSI_X_INT*SCI_MAX_CONTROLLERS)
4546f231ddaSDan Williams 
4556f231ddaSDan Williams struct isci_pci_info {
4566f231ddaSDan Williams 	struct msix_entry msix_entries[SCI_MAX_MSIX_INT];
457b329aff1SDan Williams 	struct isci_host *hosts[SCI_MAX_CONTROLLERS];
458d044af17SDan Williams 	struct isci_orom *orom;
4596f231ddaSDan Williams };
4606f231ddaSDan Williams 
4616f231ddaSDan Williams static inline struct isci_pci_info *to_pci_info(struct pci_dev *pdev)
4626f231ddaSDan Williams {
4636f231ddaSDan Williams 	return pci_get_drvdata(pdev);
4646f231ddaSDan Williams }
4656f231ddaSDan Williams 
466b329aff1SDan Williams #define for_each_isci_host(id, ihost, pdev) \
467b329aff1SDan Williams 	for (id = 0, ihost = to_pci_info(pdev)->hosts[id]; \
468b329aff1SDan Williams 	     id < ARRAY_SIZE(to_pci_info(pdev)->hosts) && ihost; \
469b329aff1SDan Williams 	     ihost = to_pci_info(pdev)->hosts[++id])
4706f231ddaSDan Williams 
471cc9203bfSDan Williams static inline enum isci_status isci_host_get_state(struct isci_host *isci_host)
4726f231ddaSDan Williams {
4736f231ddaSDan Williams 	return isci_host->status;
4746f231ddaSDan Williams }
4756f231ddaSDan Williams 
476cc9203bfSDan Williams static inline void isci_host_change_state(struct isci_host *isci_host,
4776f231ddaSDan Williams 					  enum isci_status status)
4786f231ddaSDan Williams {
4796f231ddaSDan Williams 	unsigned long flags;
4806f231ddaSDan Williams 
4816f231ddaSDan Williams 	dev_dbg(&isci_host->pdev->dev,
4826f231ddaSDan Williams 		"%s: isci_host = %p, state = 0x%x",
4836f231ddaSDan Williams 		__func__,
4846f231ddaSDan Williams 		isci_host,
4856f231ddaSDan Williams 		status);
4866f231ddaSDan Williams 	spin_lock_irqsave(&isci_host->state_lock, flags);
4876f231ddaSDan Williams 	isci_host->status = status;
4886f231ddaSDan Williams 	spin_unlock_irqrestore(&isci_host->state_lock, flags);
4896f231ddaSDan Williams 
4906f231ddaSDan Williams }
4916f231ddaSDan Williams 
492cc9203bfSDan Williams static inline int isci_host_can_queue(struct isci_host *isci_host, int num)
4936f231ddaSDan Williams {
4946f231ddaSDan Williams 	int ret = 0;
4956f231ddaSDan Williams 	unsigned long flags;
4966f231ddaSDan Williams 
4976f231ddaSDan Williams 	spin_lock_irqsave(&isci_host->queue_lock, flags);
4986f231ddaSDan Williams 	if ((isci_host->can_queue - num) < 0) {
4996f231ddaSDan Williams 		dev_dbg(&isci_host->pdev->dev,
5006f231ddaSDan Williams 			"%s: isci_host->can_queue = %d\n",
5016f231ddaSDan Williams 			__func__,
5026f231ddaSDan Williams 			isci_host->can_queue);
5036f231ddaSDan Williams 		ret = -SAS_QUEUE_FULL;
5046f231ddaSDan Williams 
5056f231ddaSDan Williams 	} else
5066f231ddaSDan Williams 		isci_host->can_queue -= num;
5076f231ddaSDan Williams 
5086f231ddaSDan Williams 	spin_unlock_irqrestore(&isci_host->queue_lock, flags);
5096f231ddaSDan Williams 
5106f231ddaSDan Williams 	return ret;
5116f231ddaSDan Williams }
5126f231ddaSDan Williams 
513cc9203bfSDan Williams static inline void isci_host_can_dequeue(struct isci_host *isci_host, int num)
5146f231ddaSDan Williams {
5156f231ddaSDan Williams 	unsigned long flags;
5166f231ddaSDan Williams 
5176f231ddaSDan Williams 	spin_lock_irqsave(&isci_host->queue_lock, flags);
5186f231ddaSDan Williams 	isci_host->can_queue += num;
5196f231ddaSDan Williams 	spin_unlock_irqrestore(&isci_host->queue_lock, flags);
5206f231ddaSDan Williams }
5216f231ddaSDan Williams 
5220cf89d1dSDan Williams static inline void wait_for_start(struct isci_host *ihost)
5230cf89d1dSDan Williams {
5240cf89d1dSDan Williams 	wait_event(ihost->eventq, !test_bit(IHOST_START_PENDING, &ihost->flags));
5250cf89d1dSDan Williams }
5260cf89d1dSDan Williams 
5270cf89d1dSDan Williams static inline void wait_for_stop(struct isci_host *ihost)
5280cf89d1dSDan Williams {
5290cf89d1dSDan Williams 	wait_event(ihost->eventq, !test_bit(IHOST_STOP_PENDING, &ihost->flags));
5300cf89d1dSDan Williams }
5310cf89d1dSDan Williams 
5326ad31fecSDan Williams static inline void wait_for_device_start(struct isci_host *ihost, struct isci_remote_device *idev)
5336ad31fecSDan Williams {
5346ad31fecSDan Williams 	wait_event(ihost->eventq, !test_bit(IDEV_START_PENDING, &idev->flags));
5356ad31fecSDan Williams }
5366ad31fecSDan Williams 
5376ad31fecSDan Williams static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_remote_device *idev)
5386ad31fecSDan Williams {
539d9c37390SDan Williams 	wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags));
5406ad31fecSDan Williams }
5410cf89d1dSDan Williams 
5424393aa4eSDan Williams static inline struct isci_host *dev_to_ihost(struct domain_device *dev)
5434393aa4eSDan Williams {
5444393aa4eSDan Williams 	return dev->port->ha->lldd_ha;
5454393aa4eSDan Williams }
5466f231ddaSDan Williams 
547cc3dbd0aSArtur Wojcik static inline struct isci_host *scic_to_ihost(struct scic_sds_controller *scic)
548cc3dbd0aSArtur Wojcik {
549cc3dbd0aSArtur Wojcik 	/* XXX delete after merging scic_sds_contoller and isci_host */
550cc3dbd0aSArtur Wojcik 	struct isci_host *ihost = container_of(scic, typeof(*ihost), sci);
551cc3dbd0aSArtur Wojcik 
552cc3dbd0aSArtur Wojcik 	return ihost;
553cc3dbd0aSArtur Wojcik }
554cc3dbd0aSArtur Wojcik 
5556f231ddaSDan Williams /**
556cc9203bfSDan Williams  * INCREMENT_QUEUE_GET() -
5576f231ddaSDan Williams  *
558cc9203bfSDan Williams  * This macro will increment the specified index to and if the index wraps to 0
559cc9203bfSDan Williams  * it will toggel the cycle bit.
5606f231ddaSDan Williams  */
561cc9203bfSDan Williams #define INCREMENT_QUEUE_GET(index, cycle, entry_count, bit_toggle) \
562cc9203bfSDan Williams 	{ \
563cc9203bfSDan Williams 		if ((index) + 1 == entry_count) {	\
564cc9203bfSDan Williams 			(index) = 0; \
565cc9203bfSDan Williams 			(cycle) = (cycle) ^ (bit_toggle); \
566cc9203bfSDan Williams 		} else { \
567cc9203bfSDan Williams 			index = index + 1; \
568cc9203bfSDan Williams 		} \
569cc9203bfSDan Williams 	}
5706f231ddaSDan Williams 
5716f231ddaSDan Williams /**
572cc9203bfSDan Williams  * scic_sds_controller_get_port_configuration_agent() -
5736f231ddaSDan Williams  *
574cc9203bfSDan Williams  * This is a helper macro to get the port configuration agent from the
575cc9203bfSDan Williams  * controller object.
5766f231ddaSDan Williams  */
577cc9203bfSDan Williams #define scic_sds_controller_get_port_configuration_agent(controller) \
578cc9203bfSDan Williams 	(&(controller)->port_agent)
5796f231ddaSDan Williams 
5806f231ddaSDan Williams /**
581cc9203bfSDan Williams  * scic_sds_controller_get_protocol_engine_group() -
5826f231ddaSDan Williams  *
583cc9203bfSDan Williams  * This macro returns the protocol engine group for this controller object.
584cc9203bfSDan Williams  * Presently we only support protocol engine group 0 so just return that
5856f231ddaSDan Williams  */
586cc9203bfSDan Williams #define scic_sds_controller_get_protocol_engine_group(controller) 0
5876f231ddaSDan Williams 
588cc9203bfSDan Williams /**
589cc9203bfSDan Williams  * scic_sds_io_tag_construct() -
590cc9203bfSDan Williams  *
591cc9203bfSDan Williams  * This macro constructs an IO tag from the sequence and index values.
592cc9203bfSDan Williams  */
593cc9203bfSDan Williams #define scic_sds_io_tag_construct(sequence, task_index)	\
594cc9203bfSDan Williams 	((sequence) << 12 | (task_index))
595cc9203bfSDan Williams 
596cc9203bfSDan Williams /**
597cc9203bfSDan Williams  * scic_sds_io_tag_get_sequence() -
598cc9203bfSDan Williams  *
599cc9203bfSDan Williams  * This macro returns the IO sequence from the IO tag value.
600cc9203bfSDan Williams  */
601cc9203bfSDan Williams #define scic_sds_io_tag_get_sequence(io_tag) \
602cc9203bfSDan Williams 	(((io_tag) & 0xF000) >> 12)
603cc9203bfSDan Williams 
604cc9203bfSDan Williams /**
605cc9203bfSDan Williams  * scic_sds_io_tag_get_index() -
606cc9203bfSDan Williams  *
607cc9203bfSDan Williams  * This macro returns the TCi from the io tag value
608cc9203bfSDan Williams  */
609cc9203bfSDan Williams #define scic_sds_io_tag_get_index(io_tag) \
610cc9203bfSDan Williams 	((io_tag) & 0x0FFF)
611cc9203bfSDan Williams 
612cc9203bfSDan Williams /**
613cc9203bfSDan Williams  * scic_sds_io_sequence_increment() -
614cc9203bfSDan Williams  *
615cc9203bfSDan Williams  * This is a helper macro to increment the io sequence count. We may find in
616cc9203bfSDan Williams  * the future that it will be faster to store the sequence count in such a way
617cc9203bfSDan Williams  * as we dont perform the shift operation to build io tag values so therefore
618cc9203bfSDan Williams  * need a way to incrment them correctly
619cc9203bfSDan Williams  */
620cc9203bfSDan Williams #define scic_sds_io_sequence_increment(value) \
621cc9203bfSDan Williams 	((value) = (((value) + 1) & 0x000F))
622cc9203bfSDan Williams 
623cc9203bfSDan Williams /* expander attached sata devices require 3 rnc slots */
624cc9203bfSDan Williams static inline int scic_sds_remote_device_node_count(struct scic_sds_remote_device *sci_dev)
625cc9203bfSDan Williams {
626cc9203bfSDan Williams 	struct domain_device *dev = sci_dev_to_domain(sci_dev);
627cc9203bfSDan Williams 
628cc9203bfSDan Williams 	if ((dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) &&
629cc9203bfSDan Williams 	    !sci_dev->is_direct_attached)
630cc9203bfSDan Williams 		return SCU_STP_REMOTE_NODE_COUNT;
631cc9203bfSDan Williams 	return SCU_SSP_REMOTE_NODE_COUNT;
632cc9203bfSDan Williams }
633cc9203bfSDan Williams 
634cc9203bfSDan Williams /**
635cc9203bfSDan Williams  * scic_sds_controller_set_invalid_phy() -
636cc9203bfSDan Williams  *
637cc9203bfSDan Williams  * This macro will set the bit in the invalid phy mask for this controller
638cc9203bfSDan Williams  * object.  This is used to control messages reported for invalid link up
639cc9203bfSDan Williams  * notifications.
640cc9203bfSDan Williams  */
641cc9203bfSDan Williams #define scic_sds_controller_set_invalid_phy(controller, phy) \
642cc9203bfSDan Williams 	((controller)->invalid_phy_mask |= (1 << (phy)->phy_index))
643cc9203bfSDan Williams 
644cc9203bfSDan Williams /**
645cc9203bfSDan Williams  * scic_sds_controller_clear_invalid_phy() -
646cc9203bfSDan Williams  *
647cc9203bfSDan Williams  * This macro will clear the bit in the invalid phy mask for this controller
648cc9203bfSDan Williams  * object.  This is used to control messages reported for invalid link up
649cc9203bfSDan Williams  * notifications.
650cc9203bfSDan Williams  */
651cc9203bfSDan Williams #define scic_sds_controller_clear_invalid_phy(controller, phy) \
652cc9203bfSDan Williams 	((controller)->invalid_phy_mask &= ~(1 << (phy)->phy_index))
653cc9203bfSDan Williams 
654cc9203bfSDan Williams static inline struct device *scic_to_dev(struct scic_sds_controller *scic)
655cc9203bfSDan Williams {
656cc9203bfSDan Williams 	return &scic_to_ihost(scic)->pdev->dev;
657cc9203bfSDan Williams }
658cc9203bfSDan Williams 
659cc9203bfSDan Williams static inline struct device *sciphy_to_dev(struct scic_sds_phy *sci_phy)
660cc9203bfSDan Williams {
661cc9203bfSDan Williams 	struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
662cc9203bfSDan Williams 
663cc9203bfSDan Williams 	if (!iphy || !iphy->isci_port || !iphy->isci_port->isci_host)
664cc9203bfSDan Williams 		return NULL;
665cc9203bfSDan Williams 
666cc9203bfSDan Williams 	return &iphy->isci_port->isci_host->pdev->dev;
667cc9203bfSDan Williams }
668cc9203bfSDan Williams 
669cc9203bfSDan Williams static inline struct device *sciport_to_dev(struct scic_sds_port *sci_port)
670cc9203bfSDan Williams {
671cc9203bfSDan Williams 	struct isci_port *iport = sci_port_to_iport(sci_port);
672cc9203bfSDan Williams 
673cc9203bfSDan Williams 	if (!iport || !iport->isci_host)
674cc9203bfSDan Williams 		return NULL;
675cc9203bfSDan Williams 
676cc9203bfSDan Williams 	return &iport->isci_host->pdev->dev;
677cc9203bfSDan Williams }
678cc9203bfSDan Williams 
679cc9203bfSDan Williams static inline struct device *scirdev_to_dev(struct scic_sds_remote_device *sci_dev)
680cc9203bfSDan Williams {
681cc9203bfSDan Williams 	struct isci_remote_device *idev =
682cc9203bfSDan Williams 			container_of(sci_dev, typeof(*idev), sci);
683cc9203bfSDan Williams 
684cc9203bfSDan Williams 	if (!idev || !idev->isci_port || !idev->isci_port->isci_host)
685cc9203bfSDan Williams 		return NULL;
686cc9203bfSDan Williams 
687cc9203bfSDan Williams 	return &idev->isci_port->isci_host->pdev->dev;
688cc9203bfSDan Williams }
689cc9203bfSDan Williams 
690cc9203bfSDan Williams enum {
691cc9203bfSDan Williams 	ISCI_SI_REVA0,
692cc9203bfSDan Williams 	ISCI_SI_REVA2,
693cc9203bfSDan Williams 	ISCI_SI_REVB0,
694cc9203bfSDan Williams };
695cc9203bfSDan Williams 
696cc9203bfSDan Williams extern int isci_si_rev;
697cc9203bfSDan Williams 
698cc9203bfSDan Williams static inline bool is_a0(void)
699cc9203bfSDan Williams {
700cc9203bfSDan Williams 	return isci_si_rev == ISCI_SI_REVA0;
701cc9203bfSDan Williams }
702cc9203bfSDan Williams 
703cc9203bfSDan Williams static inline bool is_a2(void)
704cc9203bfSDan Williams {
705cc9203bfSDan Williams 	return isci_si_rev == ISCI_SI_REVA2;
706cc9203bfSDan Williams }
707cc9203bfSDan Williams 
708cc9203bfSDan Williams static inline bool is_b0(void)
709cc9203bfSDan Williams {
710cc9203bfSDan Williams 	return isci_si_rev > ISCI_SI_REVA2;
711cc9203bfSDan Williams }
712cc9203bfSDan Williams 
713cc9203bfSDan Williams void scic_sds_controller_post_request(struct scic_sds_controller *scic,
714cc9203bfSDan Williams 				      u32 request);
715cc9203bfSDan Williams void scic_sds_controller_release_frame(struct scic_sds_controller *scic,
716cc9203bfSDan Williams 				       u32 frame_index);
717cc9203bfSDan Williams void scic_sds_controller_copy_sata_response(void *response_buffer,
718cc9203bfSDan Williams 					    void *frame_header,
719cc9203bfSDan Williams 					    void *frame_buffer);
720cc9203bfSDan Williams enum sci_status scic_sds_controller_allocate_remote_node_context(struct scic_sds_controller *scic,
721cc9203bfSDan Williams 								 struct scic_sds_remote_device *sci_dev,
722cc9203bfSDan Williams 								 u16 *node_id);
723cc9203bfSDan Williams void scic_sds_controller_free_remote_node_context(
724cc9203bfSDan Williams 	struct scic_sds_controller *scic,
725cc9203bfSDan Williams 	struct scic_sds_remote_device *sci_dev,
726cc9203bfSDan Williams 	u16 node_id);
727cc9203bfSDan Williams union scu_remote_node_context *scic_sds_controller_get_remote_node_context_buffer(
728cc9203bfSDan Williams 	struct scic_sds_controller *scic,
729cc9203bfSDan Williams 	u16 node_id);
730cc9203bfSDan Williams 
731cc9203bfSDan Williams struct scic_sds_request *scic_request_by_tag(struct scic_sds_controller *scic,
732cc9203bfSDan Williams 					     u16 io_tag);
733cc9203bfSDan Williams 
734cc9203bfSDan Williams struct scu_task_context *scic_sds_controller_get_task_context_buffer(
735cc9203bfSDan Williams 	struct scic_sds_controller *scic,
736cc9203bfSDan Williams 	u16 io_tag);
737cc9203bfSDan Williams 
738cc9203bfSDan Williams void scic_sds_controller_power_control_queue_insert(
739cc9203bfSDan Williams 	struct scic_sds_controller *scic,
740cc9203bfSDan Williams 	struct scic_sds_phy *sci_phy);
741cc9203bfSDan Williams 
742cc9203bfSDan Williams void scic_sds_controller_power_control_queue_remove(
743cc9203bfSDan Williams 	struct scic_sds_controller *scic,
744cc9203bfSDan Williams 	struct scic_sds_phy *sci_phy);
745cc9203bfSDan Williams 
746cc9203bfSDan Williams void scic_sds_controller_link_up(
747cc9203bfSDan Williams 	struct scic_sds_controller *scic,
748cc9203bfSDan Williams 	struct scic_sds_port *sci_port,
749cc9203bfSDan Williams 	struct scic_sds_phy *sci_phy);
750cc9203bfSDan Williams 
751cc9203bfSDan Williams void scic_sds_controller_link_down(
752cc9203bfSDan Williams 	struct scic_sds_controller *scic,
753cc9203bfSDan Williams 	struct scic_sds_port *sci_port,
754cc9203bfSDan Williams 	struct scic_sds_phy *sci_phy);
755cc9203bfSDan Williams 
756cc9203bfSDan Williams void scic_sds_controller_remote_device_stopped(
757cc9203bfSDan Williams 	struct scic_sds_controller *scic,
758cc9203bfSDan Williams 	struct scic_sds_remote_device *sci_dev);
759cc9203bfSDan Williams 
760cc9203bfSDan Williams void scic_sds_controller_copy_task_context(
761cc9203bfSDan Williams 	struct scic_sds_controller *scic,
762cc9203bfSDan Williams 	struct scic_sds_request *this_request);
763cc9203bfSDan Williams 
764cc9203bfSDan Williams void scic_sds_controller_register_setup(struct scic_sds_controller *scic);
765cc9203bfSDan Williams 
766cc9203bfSDan Williams enum sci_status scic_controller_continue_io(struct scic_sds_request *sci_req);
767cc9203bfSDan Williams int isci_host_scan_finished(struct Scsi_Host *, unsigned long);
768cc9203bfSDan Williams void isci_host_scan_start(struct Scsi_Host *);
7696f231ddaSDan Williams 
7706f231ddaSDan Williams int isci_host_init(struct isci_host *);
7716f231ddaSDan Williams 
7726f231ddaSDan Williams void isci_host_init_controller_names(
7736f231ddaSDan Williams 	struct isci_host *isci_host,
7746f231ddaSDan Williams 	unsigned int controller_idx);
7756f231ddaSDan Williams 
7766f231ddaSDan Williams void isci_host_deinit(
7776f231ddaSDan Williams 	struct isci_host *);
7786f231ddaSDan Williams 
7796f231ddaSDan Williams void isci_host_port_link_up(
7806f231ddaSDan Williams 	struct isci_host *,
7816f231ddaSDan Williams 	struct scic_sds_port *,
7826f231ddaSDan Williams 	struct scic_sds_phy *);
7836f231ddaSDan Williams int isci_host_dev_found(struct domain_device *);
7846f231ddaSDan Williams 
7856f231ddaSDan Williams void isci_host_remote_device_start_complete(
7866f231ddaSDan Williams 	struct isci_host *,
7876f231ddaSDan Williams 	struct isci_remote_device *,
7886f231ddaSDan Williams 	enum sci_status);
7896f231ddaSDan Williams 
790cc9203bfSDan Williams void scic_controller_disable_interrupts(
791cc9203bfSDan Williams 	struct scic_sds_controller *scic);
792cc9203bfSDan Williams 
793cc9203bfSDan Williams enum sci_status scic_controller_start_io(
794cc9203bfSDan Williams 	struct scic_sds_controller *scic,
795cc9203bfSDan Williams 	struct scic_sds_remote_device *remote_device,
796cc9203bfSDan Williams 	struct scic_sds_request *io_request,
797cc9203bfSDan Williams 	u16 io_tag);
798cc9203bfSDan Williams 
799cc9203bfSDan Williams enum sci_task_status scic_controller_start_task(
800cc9203bfSDan Williams 	struct scic_sds_controller *scic,
801cc9203bfSDan Williams 	struct scic_sds_remote_device *remote_device,
802cc9203bfSDan Williams 	struct scic_sds_request *task_request,
803cc9203bfSDan Williams 	u16 io_tag);
804cc9203bfSDan Williams 
805cc9203bfSDan Williams enum sci_status scic_controller_terminate_request(
806cc9203bfSDan Williams 	struct scic_sds_controller *scic,
807cc9203bfSDan Williams 	struct scic_sds_remote_device *remote_device,
808cc9203bfSDan Williams 	struct scic_sds_request *request);
809cc9203bfSDan Williams 
810cc9203bfSDan Williams enum sci_status scic_controller_complete_io(
811cc9203bfSDan Williams 	struct scic_sds_controller *scic,
812cc9203bfSDan Williams 	struct scic_sds_remote_device *remote_device,
813cc9203bfSDan Williams 	struct scic_sds_request *io_request);
814cc9203bfSDan Williams 
815cc9203bfSDan Williams u16 scic_controller_allocate_io_tag(
816cc9203bfSDan Williams 	struct scic_sds_controller *scic);
817cc9203bfSDan Williams 
818cc9203bfSDan Williams enum sci_status scic_controller_free_io_tag(
819cc9203bfSDan Williams 	struct scic_sds_controller *scic,
820cc9203bfSDan Williams 	u16 io_tag);
821e2f8db50SDan Williams 
822e2f8db50SDan Williams void scic_sds_port_configuration_agent_construct(
823e2f8db50SDan Williams 	struct scic_sds_port_configuration_agent *port_agent);
824e2f8db50SDan Williams 
825e2f8db50SDan Williams enum sci_status scic_sds_port_configuration_agent_initialize(
826e2f8db50SDan Williams 	struct scic_sds_controller *controller,
827e2f8db50SDan Williams 	struct scic_sds_port_configuration_agent *port_agent);
828cc9203bfSDan Williams #endif
829