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 /** 140*6cb5853dSEdmund Nadolski * Timer for controller start/stop operations. 141cc9203bfSDan Williams */ 142*6cb5853dSEdmund 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 /** 274cc9203bfSDan Williams * This field is the driver timer handle for controller phy request startup. 275cc9203bfSDan Williams * On controller start the controller will start each PHY individually in 276cc9203bfSDan Williams * order of phy index. 277cc9203bfSDan Williams */ 278cc9203bfSDan Williams void *phy_startup_timer; 279cc9203bfSDan Williams 280cc9203bfSDan Williams /** 281cc9203bfSDan Williams * This field is set when the phy_startup_timer is running and is cleared when 282cc9203bfSDan Williams * the phy_startup_timer is stopped. 283cc9203bfSDan Williams */ 284cc9203bfSDan Williams bool phy_startup_timer_pending; 285cc9203bfSDan Williams 286cc9203bfSDan Williams /** 287cc9203bfSDan Williams * This field is the index of the next phy start. It is initialized to 0 and 288cc9203bfSDan Williams * increments for each phy index that is started. 289cc9203bfSDan Williams */ 290cc9203bfSDan Williams u32 next_phy_to_start; 291cc9203bfSDan Williams 292cc9203bfSDan Williams /** 293cc9203bfSDan Williams * This field controlls the invalid link up notifications to the SCI_USER. If 294cc9203bfSDan Williams * an invalid_link_up notification is reported a bit for the PHY index is set 295cc9203bfSDan Williams * so further notifications are not made. Once the PHY object reports link up 296cc9203bfSDan Williams * and is made part of a port then this bit for the PHY index is cleared. 297cc9203bfSDan Williams */ 298cc9203bfSDan Williams u8 invalid_phy_mask; 299cc9203bfSDan Williams 300cc9203bfSDan Williams /* 301cc9203bfSDan Williams * This field saves the current interrupt coalescing number of the controller. 302cc9203bfSDan Williams */ 303cc9203bfSDan Williams u16 interrupt_coalesce_number; 304cc9203bfSDan Williams 305cc9203bfSDan Williams /* 306cc9203bfSDan Williams * This field saves the current interrupt coalescing timeout value in microseconds. 307cc9203bfSDan Williams */ 308cc9203bfSDan Williams u32 interrupt_coalesce_timeout; 309cc9203bfSDan Williams 310cc9203bfSDan Williams /** 311cc9203bfSDan Williams * This field is a pointer to the memory mapped register space for the 312cc9203bfSDan Williams * struct smu_registers. 313cc9203bfSDan Williams */ 314cc9203bfSDan Williams struct smu_registers __iomem *smu_registers; 315cc9203bfSDan Williams 316cc9203bfSDan Williams /** 317cc9203bfSDan Williams * This field is a pointer to the memory mapped register space for the 318cc9203bfSDan Williams * struct scu_registers. 319cc9203bfSDan Williams */ 320cc9203bfSDan Williams struct scu_registers __iomem *scu_registers; 321cc9203bfSDan Williams 322cc9203bfSDan Williams }; 3236f231ddaSDan Williams 3246f231ddaSDan Williams struct isci_host { 325cc3dbd0aSArtur Wojcik struct scic_sds_controller sci; 3266f231ddaSDan Williams union scic_oem_parameters oem_parameters; 3276f231ddaSDan Williams 3286f231ddaSDan Williams int id; /* unique within a given pci device */ 3297c40a803SDan Williams struct list_head timers; 3306f231ddaSDan Williams void *core_ctrl_memory; 3316f231ddaSDan Williams struct dma_pool *dma_pool; 3326f231ddaSDan Williams struct isci_phy phys[SCI_MAX_PHYS]; 333e531381eSDan Williams struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */ 3346f231ddaSDan Williams struct sas_ha_struct sas_ha; 3356f231ddaSDan Williams 3366f231ddaSDan Williams int can_queue; 3376f231ddaSDan Williams spinlock_t queue_lock; 3386f231ddaSDan Williams spinlock_t state_lock; 3396f231ddaSDan Williams 3406f231ddaSDan Williams struct pci_dev *pdev; 3416f231ddaSDan Williams 3426f231ddaSDan Williams enum isci_status status; 3430cf89d1dSDan Williams #define IHOST_START_PENDING 0 3440cf89d1dSDan Williams #define IHOST_STOP_PENDING 1 3450cf89d1dSDan Williams unsigned long flags; 3460cf89d1dSDan Williams wait_queue_head_t eventq; 3476f231ddaSDan Williams struct Scsi_Host *shost; 3486f231ddaSDan Williams struct tasklet_struct completion_tasklet; 3496f231ddaSDan Williams struct list_head requests_to_complete; 35011b00c19SJeff Skirvin struct list_head requests_to_errorback; 3516f231ddaSDan Williams spinlock_t scic_lock; 352d9c37390SDan Williams 35357f20f4eSDan Williams struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES]; 3546f231ddaSDan Williams }; 3556f231ddaSDan Williams 3566f231ddaSDan Williams /** 357cc9203bfSDan Williams * enum scic_sds_controller_states - This enumeration depicts all the states 358cc9203bfSDan Williams * for the common controller state machine. 359cc9203bfSDan Williams */ 360cc9203bfSDan Williams enum scic_sds_controller_states { 361cc9203bfSDan Williams /** 362cc9203bfSDan Williams * Simply the initial state for the base controller state machine. 363cc9203bfSDan Williams */ 364cc9203bfSDan Williams SCI_BASE_CONTROLLER_STATE_INITIAL = 0, 365cc9203bfSDan Williams 366cc9203bfSDan Williams /** 367cc9203bfSDan Williams * This state indicates that the controller is reset. The memory for 368cc9203bfSDan Williams * the controller is in it's initial state, but the controller requires 369cc9203bfSDan Williams * initialization. 370cc9203bfSDan Williams * This state is entered from the INITIAL state. 371cc9203bfSDan Williams * This state is entered from the RESETTING state. 372cc9203bfSDan Williams */ 373cc9203bfSDan Williams SCI_BASE_CONTROLLER_STATE_RESET, 374cc9203bfSDan Williams 375cc9203bfSDan Williams /** 376cc9203bfSDan Williams * This state is typically an action state that indicates the controller 377cc9203bfSDan Williams * is in the process of initialization. In this state no new IO operations 378cc9203bfSDan Williams * are permitted. 379cc9203bfSDan Williams * This state is entered from the RESET state. 380cc9203bfSDan Williams */ 381cc9203bfSDan Williams SCI_BASE_CONTROLLER_STATE_INITIALIZING, 382cc9203bfSDan Williams 383cc9203bfSDan Williams /** 384cc9203bfSDan Williams * This state indicates that the controller has been successfully 385cc9203bfSDan Williams * initialized. In this state no new IO operations are permitted. 386cc9203bfSDan Williams * This state is entered from the INITIALIZING state. 387cc9203bfSDan Williams */ 388cc9203bfSDan Williams SCI_BASE_CONTROLLER_STATE_INITIALIZED, 389cc9203bfSDan Williams 390cc9203bfSDan Williams /** 391cc9203bfSDan Williams * This state indicates the the controller is in the process of becoming 392cc9203bfSDan Williams * ready (i.e. starting). In this state no new IO operations are permitted. 393cc9203bfSDan Williams * This state is entered from the INITIALIZED state. 394cc9203bfSDan Williams */ 395cc9203bfSDan Williams SCI_BASE_CONTROLLER_STATE_STARTING, 396cc9203bfSDan Williams 397cc9203bfSDan Williams /** 398cc9203bfSDan Williams * This state indicates the controller is now ready. Thus, the user 399cc9203bfSDan Williams * is able to perform IO operations on the controller. 400cc9203bfSDan Williams * This state is entered from the STARTING state. 401cc9203bfSDan Williams */ 402cc9203bfSDan Williams SCI_BASE_CONTROLLER_STATE_READY, 403cc9203bfSDan Williams 404cc9203bfSDan Williams /** 405cc9203bfSDan Williams * This state is typically an action state that indicates the controller 406cc9203bfSDan Williams * is in the process of resetting. Thus, the user is unable to perform 407cc9203bfSDan Williams * IO operations on the controller. A reset is considered destructive in 408cc9203bfSDan Williams * most cases. 409cc9203bfSDan Williams * This state is entered from the READY state. 410cc9203bfSDan Williams * This state is entered from the FAILED state. 411cc9203bfSDan Williams * This state is entered from the STOPPED state. 412cc9203bfSDan Williams */ 413cc9203bfSDan Williams SCI_BASE_CONTROLLER_STATE_RESETTING, 414cc9203bfSDan Williams 415cc9203bfSDan Williams /** 416cc9203bfSDan Williams * This state indicates that the controller is in the process of stopping. 417cc9203bfSDan Williams * In this state no new IO operations are permitted, but existing IO 418cc9203bfSDan Williams * operations are allowed to complete. 419cc9203bfSDan Williams * This state is entered from the READY state. 420cc9203bfSDan Williams */ 421cc9203bfSDan Williams SCI_BASE_CONTROLLER_STATE_STOPPING, 422cc9203bfSDan Williams 423cc9203bfSDan Williams /** 424cc9203bfSDan Williams * This state indicates that the controller has successfully been stopped. 425cc9203bfSDan Williams * In this state no new IO operations are permitted. 426cc9203bfSDan Williams * This state is entered from the STOPPING state. 427cc9203bfSDan Williams */ 428cc9203bfSDan Williams SCI_BASE_CONTROLLER_STATE_STOPPED, 429cc9203bfSDan Williams 430cc9203bfSDan Williams /** 431cc9203bfSDan Williams * This state indicates that the controller could not successfully be 432cc9203bfSDan Williams * initialized. In this state no new IO operations are permitted. 433cc9203bfSDan Williams * This state is entered from the INITIALIZING state. 434cc9203bfSDan Williams * This state is entered from the STARTING state. 435cc9203bfSDan Williams * This state is entered from the STOPPING state. 436cc9203bfSDan Williams * This state is entered from the RESETTING state. 437cc9203bfSDan Williams */ 438cc9203bfSDan Williams SCI_BASE_CONTROLLER_STATE_FAILED, 439cc9203bfSDan Williams 440cc9203bfSDan Williams SCI_BASE_CONTROLLER_MAX_STATES 441cc9203bfSDan Williams 442cc9203bfSDan Williams }; 443cc9203bfSDan Williams 444cc9203bfSDan Williams 445cc9203bfSDan Williams 446cc9203bfSDan Williams /** 4476f231ddaSDan Williams * struct isci_pci_info - This class represents the pci function containing the 4486f231ddaSDan Williams * controllers. Depending on PCI SKU, there could be up to 2 controllers in 4496f231ddaSDan Williams * the PCI function. 4506f231ddaSDan Williams */ 4516f231ddaSDan Williams #define SCI_MAX_MSIX_INT (SCI_NUM_MSI_X_INT*SCI_MAX_CONTROLLERS) 4526f231ddaSDan Williams 4536f231ddaSDan Williams struct isci_pci_info { 4546f231ddaSDan Williams struct msix_entry msix_entries[SCI_MAX_MSIX_INT]; 455b329aff1SDan Williams struct isci_host *hosts[SCI_MAX_CONTROLLERS]; 456d044af17SDan Williams struct isci_orom *orom; 4576f231ddaSDan Williams }; 4586f231ddaSDan Williams 4596f231ddaSDan Williams static inline struct isci_pci_info *to_pci_info(struct pci_dev *pdev) 4606f231ddaSDan Williams { 4616f231ddaSDan Williams return pci_get_drvdata(pdev); 4626f231ddaSDan Williams } 4636f231ddaSDan Williams 464b329aff1SDan Williams #define for_each_isci_host(id, ihost, pdev) \ 465b329aff1SDan Williams for (id = 0, ihost = to_pci_info(pdev)->hosts[id]; \ 466b329aff1SDan Williams id < ARRAY_SIZE(to_pci_info(pdev)->hosts) && ihost; \ 467b329aff1SDan Williams ihost = to_pci_info(pdev)->hosts[++id]) 4686f231ddaSDan Williams 469cc9203bfSDan Williams static inline enum isci_status isci_host_get_state(struct isci_host *isci_host) 4706f231ddaSDan Williams { 4716f231ddaSDan Williams return isci_host->status; 4726f231ddaSDan Williams } 4736f231ddaSDan Williams 474cc9203bfSDan Williams static inline void isci_host_change_state(struct isci_host *isci_host, 4756f231ddaSDan Williams enum isci_status status) 4766f231ddaSDan Williams { 4776f231ddaSDan Williams unsigned long flags; 4786f231ddaSDan Williams 4796f231ddaSDan Williams dev_dbg(&isci_host->pdev->dev, 4806f231ddaSDan Williams "%s: isci_host = %p, state = 0x%x", 4816f231ddaSDan Williams __func__, 4826f231ddaSDan Williams isci_host, 4836f231ddaSDan Williams status); 4846f231ddaSDan Williams spin_lock_irqsave(&isci_host->state_lock, flags); 4856f231ddaSDan Williams isci_host->status = status; 4866f231ddaSDan Williams spin_unlock_irqrestore(&isci_host->state_lock, flags); 4876f231ddaSDan Williams 4886f231ddaSDan Williams } 4896f231ddaSDan Williams 490cc9203bfSDan Williams static inline int isci_host_can_queue(struct isci_host *isci_host, int num) 4916f231ddaSDan Williams { 4926f231ddaSDan Williams int ret = 0; 4936f231ddaSDan Williams unsigned long flags; 4946f231ddaSDan Williams 4956f231ddaSDan Williams spin_lock_irqsave(&isci_host->queue_lock, flags); 4966f231ddaSDan Williams if ((isci_host->can_queue - num) < 0) { 4976f231ddaSDan Williams dev_dbg(&isci_host->pdev->dev, 4986f231ddaSDan Williams "%s: isci_host->can_queue = %d\n", 4996f231ddaSDan Williams __func__, 5006f231ddaSDan Williams isci_host->can_queue); 5016f231ddaSDan Williams ret = -SAS_QUEUE_FULL; 5026f231ddaSDan Williams 5036f231ddaSDan Williams } else 5046f231ddaSDan Williams isci_host->can_queue -= num; 5056f231ddaSDan Williams 5066f231ddaSDan Williams spin_unlock_irqrestore(&isci_host->queue_lock, flags); 5076f231ddaSDan Williams 5086f231ddaSDan Williams return ret; 5096f231ddaSDan Williams } 5106f231ddaSDan Williams 511cc9203bfSDan Williams static inline void isci_host_can_dequeue(struct isci_host *isci_host, int num) 5126f231ddaSDan Williams { 5136f231ddaSDan Williams unsigned long flags; 5146f231ddaSDan Williams 5156f231ddaSDan Williams spin_lock_irqsave(&isci_host->queue_lock, flags); 5166f231ddaSDan Williams isci_host->can_queue += num; 5176f231ddaSDan Williams spin_unlock_irqrestore(&isci_host->queue_lock, flags); 5186f231ddaSDan Williams } 5196f231ddaSDan Williams 5200cf89d1dSDan Williams static inline void wait_for_start(struct isci_host *ihost) 5210cf89d1dSDan Williams { 5220cf89d1dSDan Williams wait_event(ihost->eventq, !test_bit(IHOST_START_PENDING, &ihost->flags)); 5230cf89d1dSDan Williams } 5240cf89d1dSDan Williams 5250cf89d1dSDan Williams static inline void wait_for_stop(struct isci_host *ihost) 5260cf89d1dSDan Williams { 5270cf89d1dSDan Williams wait_event(ihost->eventq, !test_bit(IHOST_STOP_PENDING, &ihost->flags)); 5280cf89d1dSDan Williams } 5290cf89d1dSDan Williams 5306ad31fecSDan Williams static inline void wait_for_device_start(struct isci_host *ihost, struct isci_remote_device *idev) 5316ad31fecSDan Williams { 5326ad31fecSDan Williams wait_event(ihost->eventq, !test_bit(IDEV_START_PENDING, &idev->flags)); 5336ad31fecSDan Williams } 5346ad31fecSDan Williams 5356ad31fecSDan Williams static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_remote_device *idev) 5366ad31fecSDan Williams { 537d9c37390SDan Williams wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags)); 5386ad31fecSDan Williams } 5390cf89d1dSDan Williams 5404393aa4eSDan Williams static inline struct isci_host *dev_to_ihost(struct domain_device *dev) 5414393aa4eSDan Williams { 5424393aa4eSDan Williams return dev->port->ha->lldd_ha; 5434393aa4eSDan Williams } 5446f231ddaSDan Williams 545cc3dbd0aSArtur Wojcik static inline struct isci_host *scic_to_ihost(struct scic_sds_controller *scic) 546cc3dbd0aSArtur Wojcik { 547cc3dbd0aSArtur Wojcik /* XXX delete after merging scic_sds_contoller and isci_host */ 548cc3dbd0aSArtur Wojcik struct isci_host *ihost = container_of(scic, typeof(*ihost), sci); 549cc3dbd0aSArtur Wojcik 550cc3dbd0aSArtur Wojcik return ihost; 551cc3dbd0aSArtur Wojcik } 552cc3dbd0aSArtur Wojcik 5536f231ddaSDan Williams /** 554cc9203bfSDan Williams * INCREMENT_QUEUE_GET() - 5556f231ddaSDan Williams * 556cc9203bfSDan Williams * This macro will increment the specified index to and if the index wraps to 0 557cc9203bfSDan Williams * it will toggel the cycle bit. 5586f231ddaSDan Williams */ 559cc9203bfSDan Williams #define INCREMENT_QUEUE_GET(index, cycle, entry_count, bit_toggle) \ 560cc9203bfSDan Williams { \ 561cc9203bfSDan Williams if ((index) + 1 == entry_count) { \ 562cc9203bfSDan Williams (index) = 0; \ 563cc9203bfSDan Williams (cycle) = (cycle) ^ (bit_toggle); \ 564cc9203bfSDan Williams } else { \ 565cc9203bfSDan Williams index = index + 1; \ 566cc9203bfSDan Williams } \ 567cc9203bfSDan Williams } 5686f231ddaSDan Williams 5696f231ddaSDan Williams /** 570cc9203bfSDan Williams * scic_sds_controller_get_protocol_engine_group() - 5716f231ddaSDan Williams * 572cc9203bfSDan Williams * This macro returns the protocol engine group for this controller object. 573cc9203bfSDan Williams * Presently we only support protocol engine group 0 so just return that 5746f231ddaSDan Williams */ 575cc9203bfSDan Williams #define scic_sds_controller_get_protocol_engine_group(controller) 0 5766f231ddaSDan Williams 577cc9203bfSDan Williams /** 578cc9203bfSDan Williams * scic_sds_io_tag_construct() - 579cc9203bfSDan Williams * 580cc9203bfSDan Williams * This macro constructs an IO tag from the sequence and index values. 581cc9203bfSDan Williams */ 582cc9203bfSDan Williams #define scic_sds_io_tag_construct(sequence, task_index) \ 583cc9203bfSDan Williams ((sequence) << 12 | (task_index)) 584cc9203bfSDan Williams 585cc9203bfSDan Williams /** 586cc9203bfSDan Williams * scic_sds_io_tag_get_sequence() - 587cc9203bfSDan Williams * 588cc9203bfSDan Williams * This macro returns the IO sequence from the IO tag value. 589cc9203bfSDan Williams */ 590cc9203bfSDan Williams #define scic_sds_io_tag_get_sequence(io_tag) \ 591cc9203bfSDan Williams (((io_tag) & 0xF000) >> 12) 592cc9203bfSDan Williams 593cc9203bfSDan Williams /** 594cc9203bfSDan Williams * scic_sds_io_tag_get_index() - 595cc9203bfSDan Williams * 596cc9203bfSDan Williams * This macro returns the TCi from the io tag value 597cc9203bfSDan Williams */ 598cc9203bfSDan Williams #define scic_sds_io_tag_get_index(io_tag) \ 599cc9203bfSDan Williams ((io_tag) & 0x0FFF) 600cc9203bfSDan Williams 601cc9203bfSDan Williams /** 602cc9203bfSDan Williams * scic_sds_io_sequence_increment() - 603cc9203bfSDan Williams * 604cc9203bfSDan Williams * This is a helper macro to increment the io sequence count. We may find in 605cc9203bfSDan Williams * the future that it will be faster to store the sequence count in such a way 606cc9203bfSDan Williams * as we dont perform the shift operation to build io tag values so therefore 607cc9203bfSDan Williams * need a way to incrment them correctly 608cc9203bfSDan Williams */ 609cc9203bfSDan Williams #define scic_sds_io_sequence_increment(value) \ 610cc9203bfSDan Williams ((value) = (((value) + 1) & 0x000F)) 611cc9203bfSDan Williams 612cc9203bfSDan Williams /* expander attached sata devices require 3 rnc slots */ 613cc9203bfSDan Williams static inline int scic_sds_remote_device_node_count(struct scic_sds_remote_device *sci_dev) 614cc9203bfSDan Williams { 615cc9203bfSDan Williams struct domain_device *dev = sci_dev_to_domain(sci_dev); 616cc9203bfSDan Williams 617cc9203bfSDan Williams if ((dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) && 618cc9203bfSDan Williams !sci_dev->is_direct_attached) 619cc9203bfSDan Williams return SCU_STP_REMOTE_NODE_COUNT; 620cc9203bfSDan Williams return SCU_SSP_REMOTE_NODE_COUNT; 621cc9203bfSDan Williams } 622cc9203bfSDan Williams 623cc9203bfSDan Williams /** 624cc9203bfSDan Williams * scic_sds_controller_set_invalid_phy() - 625cc9203bfSDan Williams * 626cc9203bfSDan Williams * This macro will set the bit in the invalid phy mask for this controller 627cc9203bfSDan Williams * object. This is used to control messages reported for invalid link up 628cc9203bfSDan Williams * notifications. 629cc9203bfSDan Williams */ 630cc9203bfSDan Williams #define scic_sds_controller_set_invalid_phy(controller, phy) \ 631cc9203bfSDan Williams ((controller)->invalid_phy_mask |= (1 << (phy)->phy_index)) 632cc9203bfSDan Williams 633cc9203bfSDan Williams /** 634cc9203bfSDan Williams * scic_sds_controller_clear_invalid_phy() - 635cc9203bfSDan Williams * 636cc9203bfSDan Williams * This macro will clear the bit in the invalid phy mask for this controller 637cc9203bfSDan Williams * object. This is used to control messages reported for invalid link up 638cc9203bfSDan Williams * notifications. 639cc9203bfSDan Williams */ 640cc9203bfSDan Williams #define scic_sds_controller_clear_invalid_phy(controller, phy) \ 641cc9203bfSDan Williams ((controller)->invalid_phy_mask &= ~(1 << (phy)->phy_index)) 642cc9203bfSDan Williams 643cc9203bfSDan Williams static inline struct device *scic_to_dev(struct scic_sds_controller *scic) 644cc9203bfSDan Williams { 645cc9203bfSDan Williams return &scic_to_ihost(scic)->pdev->dev; 646cc9203bfSDan Williams } 647cc9203bfSDan Williams 648cc9203bfSDan Williams static inline struct device *sciphy_to_dev(struct scic_sds_phy *sci_phy) 649cc9203bfSDan Williams { 650cc9203bfSDan Williams struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); 651cc9203bfSDan Williams 652cc9203bfSDan Williams if (!iphy || !iphy->isci_port || !iphy->isci_port->isci_host) 653cc9203bfSDan Williams return NULL; 654cc9203bfSDan Williams 655cc9203bfSDan Williams return &iphy->isci_port->isci_host->pdev->dev; 656cc9203bfSDan Williams } 657cc9203bfSDan Williams 658cc9203bfSDan Williams static inline struct device *sciport_to_dev(struct scic_sds_port *sci_port) 659cc9203bfSDan Williams { 660cc9203bfSDan Williams struct isci_port *iport = sci_port_to_iport(sci_port); 661cc9203bfSDan Williams 662cc9203bfSDan Williams if (!iport || !iport->isci_host) 663cc9203bfSDan Williams return NULL; 664cc9203bfSDan Williams 665cc9203bfSDan Williams return &iport->isci_host->pdev->dev; 666cc9203bfSDan Williams } 667cc9203bfSDan Williams 668cc9203bfSDan Williams static inline struct device *scirdev_to_dev(struct scic_sds_remote_device *sci_dev) 669cc9203bfSDan Williams { 670cc9203bfSDan Williams struct isci_remote_device *idev = 671cc9203bfSDan Williams container_of(sci_dev, typeof(*idev), sci); 672cc9203bfSDan Williams 673cc9203bfSDan Williams if (!idev || !idev->isci_port || !idev->isci_port->isci_host) 674cc9203bfSDan Williams return NULL; 675cc9203bfSDan Williams 676cc9203bfSDan Williams return &idev->isci_port->isci_host->pdev->dev; 677cc9203bfSDan Williams } 678cc9203bfSDan Williams 679cc9203bfSDan Williams enum { 680cc9203bfSDan Williams ISCI_SI_REVA0, 681cc9203bfSDan Williams ISCI_SI_REVA2, 682cc9203bfSDan Williams ISCI_SI_REVB0, 683cc9203bfSDan Williams }; 684cc9203bfSDan Williams 685cc9203bfSDan Williams extern int isci_si_rev; 686cc9203bfSDan Williams 687cc9203bfSDan Williams static inline bool is_a0(void) 688cc9203bfSDan Williams { 689cc9203bfSDan Williams return isci_si_rev == ISCI_SI_REVA0; 690cc9203bfSDan Williams } 691cc9203bfSDan Williams 692cc9203bfSDan Williams static inline bool is_a2(void) 693cc9203bfSDan Williams { 694cc9203bfSDan Williams return isci_si_rev == ISCI_SI_REVA2; 695cc9203bfSDan Williams } 696cc9203bfSDan Williams 697cc9203bfSDan Williams static inline bool is_b0(void) 698cc9203bfSDan Williams { 699cc9203bfSDan Williams return isci_si_rev > ISCI_SI_REVA2; 700cc9203bfSDan Williams } 701cc9203bfSDan Williams 702cc9203bfSDan Williams void scic_sds_controller_post_request(struct scic_sds_controller *scic, 703cc9203bfSDan Williams u32 request); 704cc9203bfSDan Williams void scic_sds_controller_release_frame(struct scic_sds_controller *scic, 705cc9203bfSDan Williams u32 frame_index); 706cc9203bfSDan Williams void scic_sds_controller_copy_sata_response(void *response_buffer, 707cc9203bfSDan Williams void *frame_header, 708cc9203bfSDan Williams void *frame_buffer); 709cc9203bfSDan Williams enum sci_status scic_sds_controller_allocate_remote_node_context(struct scic_sds_controller *scic, 710cc9203bfSDan Williams struct scic_sds_remote_device *sci_dev, 711cc9203bfSDan Williams u16 *node_id); 712cc9203bfSDan Williams void scic_sds_controller_free_remote_node_context( 713cc9203bfSDan Williams struct scic_sds_controller *scic, 714cc9203bfSDan Williams struct scic_sds_remote_device *sci_dev, 715cc9203bfSDan Williams u16 node_id); 716cc9203bfSDan Williams union scu_remote_node_context *scic_sds_controller_get_remote_node_context_buffer( 717cc9203bfSDan Williams struct scic_sds_controller *scic, 718cc9203bfSDan Williams u16 node_id); 719cc9203bfSDan Williams 720cc9203bfSDan Williams struct scic_sds_request *scic_request_by_tag(struct scic_sds_controller *scic, 721cc9203bfSDan Williams u16 io_tag); 722cc9203bfSDan Williams 723cc9203bfSDan Williams struct scu_task_context *scic_sds_controller_get_task_context_buffer( 724cc9203bfSDan Williams struct scic_sds_controller *scic, 725cc9203bfSDan Williams u16 io_tag); 726cc9203bfSDan Williams 727cc9203bfSDan Williams void scic_sds_controller_power_control_queue_insert( 728cc9203bfSDan Williams struct scic_sds_controller *scic, 729cc9203bfSDan Williams struct scic_sds_phy *sci_phy); 730cc9203bfSDan Williams 731cc9203bfSDan Williams void scic_sds_controller_power_control_queue_remove( 732cc9203bfSDan Williams struct scic_sds_controller *scic, 733cc9203bfSDan Williams struct scic_sds_phy *sci_phy); 734cc9203bfSDan Williams 735cc9203bfSDan Williams void scic_sds_controller_link_up( 736cc9203bfSDan Williams struct scic_sds_controller *scic, 737cc9203bfSDan Williams struct scic_sds_port *sci_port, 738cc9203bfSDan Williams struct scic_sds_phy *sci_phy); 739cc9203bfSDan Williams 740cc9203bfSDan Williams void scic_sds_controller_link_down( 741cc9203bfSDan Williams struct scic_sds_controller *scic, 742cc9203bfSDan Williams struct scic_sds_port *sci_port, 743cc9203bfSDan Williams struct scic_sds_phy *sci_phy); 744cc9203bfSDan Williams 745cc9203bfSDan Williams void scic_sds_controller_remote_device_stopped( 746cc9203bfSDan Williams struct scic_sds_controller *scic, 747cc9203bfSDan Williams struct scic_sds_remote_device *sci_dev); 748cc9203bfSDan Williams 749cc9203bfSDan Williams void scic_sds_controller_copy_task_context( 750cc9203bfSDan Williams struct scic_sds_controller *scic, 751cc9203bfSDan Williams struct scic_sds_request *this_request); 752cc9203bfSDan Williams 753cc9203bfSDan Williams void scic_sds_controller_register_setup(struct scic_sds_controller *scic); 754cc9203bfSDan Williams 755cc9203bfSDan Williams enum sci_status scic_controller_continue_io(struct scic_sds_request *sci_req); 756cc9203bfSDan Williams int isci_host_scan_finished(struct Scsi_Host *, unsigned long); 757cc9203bfSDan Williams void isci_host_scan_start(struct Scsi_Host *); 7586f231ddaSDan Williams 7596f231ddaSDan Williams int isci_host_init(struct isci_host *); 7606f231ddaSDan Williams 7616f231ddaSDan Williams void isci_host_init_controller_names( 7626f231ddaSDan Williams struct isci_host *isci_host, 7636f231ddaSDan Williams unsigned int controller_idx); 7646f231ddaSDan Williams 7656f231ddaSDan Williams void isci_host_deinit( 7666f231ddaSDan Williams struct isci_host *); 7676f231ddaSDan Williams 7686f231ddaSDan Williams void isci_host_port_link_up( 7696f231ddaSDan Williams struct isci_host *, 7706f231ddaSDan Williams struct scic_sds_port *, 7716f231ddaSDan Williams struct scic_sds_phy *); 7726f231ddaSDan Williams int isci_host_dev_found(struct domain_device *); 7736f231ddaSDan Williams 7746f231ddaSDan Williams void isci_host_remote_device_start_complete( 7756f231ddaSDan Williams struct isci_host *, 7766f231ddaSDan Williams struct isci_remote_device *, 7776f231ddaSDan Williams enum sci_status); 7786f231ddaSDan Williams 779cc9203bfSDan Williams void scic_controller_disable_interrupts( 780cc9203bfSDan Williams struct scic_sds_controller *scic); 781cc9203bfSDan Williams 782cc9203bfSDan Williams enum sci_status scic_controller_start_io( 783cc9203bfSDan Williams struct scic_sds_controller *scic, 784cc9203bfSDan Williams struct scic_sds_remote_device *remote_device, 785cc9203bfSDan Williams struct scic_sds_request *io_request, 786cc9203bfSDan Williams u16 io_tag); 787cc9203bfSDan Williams 788cc9203bfSDan Williams enum sci_task_status scic_controller_start_task( 789cc9203bfSDan Williams struct scic_sds_controller *scic, 790cc9203bfSDan Williams struct scic_sds_remote_device *remote_device, 791cc9203bfSDan Williams struct scic_sds_request *task_request, 792cc9203bfSDan Williams u16 io_tag); 793cc9203bfSDan Williams 794cc9203bfSDan Williams enum sci_status scic_controller_terminate_request( 795cc9203bfSDan Williams struct scic_sds_controller *scic, 796cc9203bfSDan Williams struct scic_sds_remote_device *remote_device, 797cc9203bfSDan Williams struct scic_sds_request *request); 798cc9203bfSDan Williams 799cc9203bfSDan Williams enum sci_status scic_controller_complete_io( 800cc9203bfSDan Williams struct scic_sds_controller *scic, 801cc9203bfSDan Williams struct scic_sds_remote_device *remote_device, 802cc9203bfSDan Williams struct scic_sds_request *io_request); 803cc9203bfSDan Williams 804cc9203bfSDan Williams u16 scic_controller_allocate_io_tag( 805cc9203bfSDan Williams struct scic_sds_controller *scic); 806cc9203bfSDan Williams 807cc9203bfSDan Williams enum sci_status scic_controller_free_io_tag( 808cc9203bfSDan Williams struct scic_sds_controller *scic, 809cc9203bfSDan Williams u16 io_tag); 810e2f8db50SDan Williams 811e2f8db50SDan Williams void scic_sds_port_configuration_agent_construct( 812e2f8db50SDan Williams struct scic_sds_port_configuration_agent *port_agent); 813e2f8db50SDan Williams 814e2f8db50SDan Williams enum sci_status scic_sds_port_configuration_agent_initialize( 815e2f8db50SDan Williams struct scic_sds_controller *controller, 816e2f8db50SDan Williams struct scic_sds_port_configuration_agent *port_agent); 817cc9203bfSDan Williams #endif 818