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