port.h revision 13721e186fd31cd8475e635a89383853871fdbf1
1/* 2 * This file is provided under a dual BSD/GPLv2 license. When using or 3 * redistributing this file, you may do so under either license. 4 * 5 * GPL LICENSE SUMMARY 6 * 7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of version 2 of the GNU General Public License as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21 * The full GNU General Public License is included in this distribution 22 * in the file called LICENSE.GPL. 23 * 24 * BSD LICENSE 25 * 26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27 * All rights reserved. 28 * 29 * Redistribution and use in source and binary forms, with or without 30 * modification, are permitted provided that the following conditions 31 * are met: 32 * 33 * * Redistributions of source code must retain the above copyright 34 * notice, this list of conditions and the following disclaimer. 35 * * Redistributions in binary form must reproduce the above copyright 36 * notice, this list of conditions and the following disclaimer in 37 * the documentation and/or other materials provided with the 38 * distribution. 39 * * Neither the name of Intel Corporation nor the names of its 40 * contributors may be used to endorse or promote products derived 41 * from this software without specific prior written permission. 42 * 43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 */ 55 56#ifndef _ISCI_PORT_H_ 57#define _ISCI_PORT_H_ 58 59#include <scsi/libsas.h> 60#include "isci.h" 61#include "sas.h" 62#include "phy.h" 63 64#define SCIC_SDS_DUMMY_PORT 0xFF 65 66struct isci_phy; 67struct isci_host; 68 69enum isci_status { 70 isci_freed = 0x00, 71 isci_starting = 0x01, 72 isci_ready = 0x02, 73 isci_ready_for_io = 0x03, 74 isci_stopping = 0x04, 75 isci_stopped = 0x05, 76}; 77 78/** 79 * struct scic_sds_port 80 * 81 * The core port object provides the the abstraction for an SCU port. 82 */ 83struct scic_sds_port { 84 /** 85 * This field contains the information for the base port state machine. 86 */ 87 struct sci_base_state_machine state_machine; 88 89 bool ready_exit; 90 91 /** 92 * This field is the port index that is reported to the SCI USER. 93 * This allows the actual hardware physical port to change without 94 * the SCI USER getting a different answer for the get port index. 95 */ 96 u8 logical_port_index; 97 98 /** 99 * This field is the port index used to program the SCU hardware. 100 */ 101 u8 physical_port_index; 102 103 /** 104 * This field contains the active phy mask for the port. 105 * This mask is used in conjunction with the phy state to determine 106 * which phy to select for some port operations. 107 */ 108 u8 active_phy_mask; 109 110 u16 reserved_rni; 111 u16 reserved_tci; 112 113 /** 114 * This field contains the count of the io requests started on this port 115 * object. It is used to control controller shutdown. 116 */ 117 u32 started_request_count; 118 119 /** 120 * This field contains the number of devices assigned to this port. 121 * It is used to control port start requests. 122 */ 123 u32 assigned_device_count; 124 125 /** 126 * This field contains the reason for the port not going ready. It is 127 * assigned in the state handlers and used in the state transition. 128 */ 129 u32 not_ready_reason; 130 131 /** 132 * This field is the table of phys assigned to the port. 133 */ 134 struct scic_sds_phy *phy_table[SCI_MAX_PHYS]; 135 136 /** 137 * This field is a pointer back to the controller that owns this 138 * port object. 139 */ 140 struct scic_sds_controller *owning_controller; 141 142 /** 143 * This field contains the port start/stop timer handle. 144 */ 145 void *timer_handle; 146 147 /** 148 * This field points to the current set of state handlers for this port 149 * object. These state handlers are assigned at each enter state of 150 * the state machine. 151 */ 152 struct scic_sds_port_state_handler *state_handlers; 153 154 /* / Memory mapped hardware register space */ 155 156 /** 157 * This field is the pointer to the port task scheduler registers 158 * for the SCU hardware. 159 */ 160 struct scu_port_task_scheduler_registers __iomem 161 *port_task_scheduler_registers; 162 163 /** 164 * This field is identical for all port objects and points to the port 165 * task scheduler group PE configuration registers. 166 * It is used to assign PEs to a port. 167 */ 168 u32 __iomem *port_pe_configuration_register; 169 170 /** 171 * This field is the VIIT register space for ths port object. 172 */ 173 struct scu_viit_entry __iomem *viit_registers; 174}; 175 176 177 178/** 179 * struct isci_port - This class represents the port object used to internally 180 * represent libsas port objects. It also keeps a list of remote device 181 * objects. 182 * 183 * 184 */ 185struct isci_port { 186 enum isci_status status; 187 struct isci_host *isci_host; 188 struct asd_sas_port sas_port; 189 struct list_head remote_dev_list; 190 spinlock_t state_lock; 191 struct list_head domain_dev_list; 192 struct completion start_complete; 193 struct completion hard_reset_complete; 194 enum sci_status hard_reset_status; 195 struct scic_sds_port sci; 196}; 197 198static inline struct isci_port *sci_port_to_iport(struct scic_sds_port *sci_port) 199{ 200 struct isci_port *iport = container_of(sci_port, typeof(*iport), sci); 201 202 return iport; 203} 204 205enum scic_port_not_ready_reason_code { 206 SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS, 207 SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED, 208 SCIC_PORT_NOT_READY_INVALID_PORT_CONFIGURATION, 209 SCIC_PORT_NOT_READY_RECONFIGURING, 210 211 SCIC_PORT_NOT_READY_REASON_CODE_MAX 212}; 213 214struct scic_port_end_point_properties { 215 struct sci_sas_address sas_address; 216 struct scic_phy_proto protocols; 217}; 218 219struct scic_port_properties { 220 u32 index; 221 struct scic_port_end_point_properties local; 222 struct scic_port_end_point_properties remote; 223 u32 phy_mask; 224}; 225 226/** 227 * enum scic_sds_port_states - This enumeration depicts all the states for the 228 * common port state machine. 229 * 230 * 231 */ 232enum scic_sds_port_states { 233 /** 234 * This state indicates that the port has successfully been stopped. 235 * In this state no new IO operations are permitted. 236 * This state is entered from the STOPPING state. 237 */ 238 SCI_BASE_PORT_STATE_STOPPED, 239 240 /** 241 * This state indicates that the port is in the process of stopping. 242 * In this state no new IO operations are permitted, but existing IO 243 * operations are allowed to complete. 244 * This state is entered from the READY state. 245 */ 246 SCI_BASE_PORT_STATE_STOPPING, 247 248 /** 249 * This state indicates the port is now ready. Thus, the user is 250 * able to perform IO operations on this port. 251 * This state is entered from the STARTING state. 252 */ 253 SCI_BASE_PORT_STATE_READY, 254 255 /** 256 * The substate where the port is started and ready but has no 257 * active phys. 258 */ 259 SCIC_SDS_PORT_READY_SUBSTATE_WAITING, 260 261 /** 262 * The substate where the port is started and ready and there is 263 * at least one phy operational. 264 */ 265 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL, 266 267 /** 268 * The substate where the port is started and there was an 269 * add/remove phy event. This state is only used in Automatic 270 * Port Configuration Mode (APC) 271 */ 272 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING, 273 274 /** 275 * This state indicates the port is in the process of performing a hard 276 * reset. Thus, the user is unable to perform IO operations on this 277 * port. 278 * This state is entered from the READY state. 279 */ 280 SCI_BASE_PORT_STATE_RESETTING, 281 282 /** 283 * This state indicates the port has failed a reset request. This state 284 * is entered when a port reset request times out. 285 * This state is entered from the RESETTING state. 286 */ 287 SCI_BASE_PORT_STATE_FAILED, 288 289 SCI_BASE_PORT_MAX_STATES 290 291}; 292 293struct scic_sds_remote_device; 294struct scic_sds_request; 295 296typedef enum sci_status (*scic_sds_port_handler_t)(struct scic_sds_port *); 297 298typedef enum sci_status (*scic_sds_port_phy_handler_t)(struct scic_sds_port *, 299 struct scic_sds_phy *); 300 301typedef enum sci_status (*scic_sds_port_reset_handler_t)(struct scic_sds_port *, 302 u32 timeout); 303 304typedef enum sci_status (*scic_sds_port_event_handler_t)(struct scic_sds_port *, u32); 305 306typedef enum sci_status (*scic_sds_port_frame_handler_t)(struct scic_sds_port *, u32); 307 308typedef void (*scic_sds_port_link_handler_t)(struct scic_sds_port *, struct scic_sds_phy *); 309 310typedef enum sci_status (*scic_sds_port_io_request_handler_t)(struct scic_sds_port *, 311 struct scic_sds_remote_device *, 312 struct scic_sds_request *); 313 314struct scic_sds_port_state_handler { 315 scic_sds_port_link_handler_t link_up_handler; 316 scic_sds_port_link_handler_t link_down_handler; 317 318 scic_sds_port_io_request_handler_t start_io_handler; 319 scic_sds_port_io_request_handler_t complete_io_handler; 320}; 321 322/** 323 * scic_sds_port_get_controller() - 324 * 325 * Helper macro to get the owning controller of this port 326 */ 327#define scic_sds_port_get_controller(this_port) \ 328 ((this_port)->owning_controller) 329 330/** 331 * scic_sds_port_set_base_state_handlers() - 332 * 333 * This macro will change the state handlers to those of the specified state id 334 */ 335#define scic_sds_port_set_base_state_handlers(this_port, state_id) \ 336 scic_sds_port_set_state_handlers(\ 337 (this_port), &scic_sds_port_state_handler_table[(state_id)]) 338 339/** 340 * scic_sds_port_set_state_handlers() - 341 * 342 * Helper macro to set the port object state handlers 343 */ 344#define scic_sds_port_set_state_handlers(this_port, handlers) \ 345 ((this_port)->state_handlers = (handlers)) 346 347/** 348 * scic_sds_port_get_index() - 349 * 350 * This macro returns the physical port index for this port object 351 */ 352#define scic_sds_port_get_index(this_port) \ 353 ((this_port)->physical_port_index) 354 355 356static inline void scic_sds_port_decrement_request_count(struct scic_sds_port *sci_port) 357{ 358 if (WARN_ONCE(sci_port->started_request_count == 0, 359 "%s: tried to decrement started_request_count past 0!?", 360 __func__)) 361 /* pass */; 362 else 363 sci_port->started_request_count--; 364} 365 366#define scic_sds_port_active_phy(port, phy) \ 367 (((port)->active_phy_mask & (1 << (phy)->phy_index)) != 0) 368 369void scic_sds_port_construct( 370 struct scic_sds_port *sci_port, 371 u8 port_index, 372 struct scic_sds_controller *scic); 373 374enum sci_status scic_sds_port_initialize( 375 struct scic_sds_port *sci_port, 376 void __iomem *port_task_scheduler_registers, 377 void __iomem *port_configuration_regsiter, 378 void __iomem *viit_registers); 379 380enum sci_status scic_sds_port_start(struct scic_sds_port *sci_port); 381enum sci_status scic_sds_port_stop(struct scic_sds_port *sci_port); 382 383enum sci_status scic_sds_port_add_phy( 384 struct scic_sds_port *sci_port, 385 struct scic_sds_phy *sci_phy); 386 387enum sci_status scic_sds_port_remove_phy( 388 struct scic_sds_port *sci_port, 389 struct scic_sds_phy *sci_phy); 390 391void scic_sds_port_setup_transports( 392 struct scic_sds_port *sci_port, 393 u32 device_id); 394 395 396void scic_sds_port_deactivate_phy( 397 struct scic_sds_port *sci_port, 398 struct scic_sds_phy *sci_phy, 399 bool do_notify_user); 400 401bool scic_sds_port_link_detected( 402 struct scic_sds_port *sci_port, 403 struct scic_sds_phy *sci_phy); 404 405void scic_sds_port_link_up( 406 struct scic_sds_port *sci_port, 407 struct scic_sds_phy *sci_phy); 408 409void scic_sds_port_link_down( 410 struct scic_sds_port *sci_port, 411 struct scic_sds_phy *sci_phy); 412 413enum sci_status scic_sds_port_start_io( 414 struct scic_sds_port *sci_port, 415 struct scic_sds_remote_device *sci_dev, 416 struct scic_sds_request *sci_req); 417 418enum sci_status scic_sds_port_complete_io( 419 struct scic_sds_port *sci_port, 420 struct scic_sds_remote_device *sci_dev, 421 struct scic_sds_request *sci_req); 422 423enum sas_linkrate scic_sds_port_get_max_allowed_speed( 424 struct scic_sds_port *sci_port); 425 426void scic_sds_port_broadcast_change_received( 427 struct scic_sds_port *sci_port, 428 struct scic_sds_phy *sci_phy); 429 430bool scic_sds_port_is_valid_phy_assignment( 431 struct scic_sds_port *sci_port, 432 u32 phy_index); 433 434void scic_sds_port_get_sas_address( 435 struct scic_sds_port *sci_port, 436 struct sci_sas_address *sas_address); 437 438void scic_sds_port_get_attached_sas_address( 439 struct scic_sds_port *sci_port, 440 struct sci_sas_address *sas_address); 441 442enum isci_status isci_port_get_state( 443 struct isci_port *isci_port); 444 445void isci_port_formed(struct asd_sas_phy *); 446void isci_port_deformed(struct asd_sas_phy *); 447 448void isci_port_init( 449 struct isci_port *port, 450 struct isci_host *host, 451 int index); 452 453int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport, 454 struct isci_phy *iphy); 455#endif /* !defined(_ISCI_PORT_H_) */ 456