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