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