port.c (d35bc1bd18ab9e986cfb67c5a281a70cfd717f05) | port.c (e2f8db509fdd354bb7a68c86515e9d2d8909ccc9) |
---|---|
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 * --- 39 unchanged lines hidden (view full) --- 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 | 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 * --- 39 unchanged lines hidden (view full) --- 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#include <linux/workqueue.h> | |
57#include "isci.h" | 56#include "isci.h" |
58#include "scic_port.h" | |
59#include "port.h" 60#include "request.h" | 57#include "port.h" 58#include "request.h" |
59#include "timers.h" |
|
61 | 60 |
61#define SCIC_SDS_PORT_HARD_RESET_TIMEOUT (1000) 62#define SCU_DUMMY_INDEX (0xFFFF) 63 |
|
62static void isci_port_change_state(struct isci_port *iport, enum isci_status status) 63{ 64 unsigned long flags; 65 66 dev_dbg(&iport->isci_host->pdev->dev, 67 "%s: iport = %p, state = 0x%x\n", 68 __func__, iport, status); 69 70 /* XXX pointless lock */ 71 spin_lock_irqsave(&iport->state_lock, flags); 72 iport->status = status; 73 spin_unlock_irqrestore(&iport->state_lock, flags); 74} 75 | 64static void isci_port_change_state(struct isci_port *iport, enum isci_status status) 65{ 66 unsigned long flags; 67 68 dev_dbg(&iport->isci_host->pdev->dev, 69 "%s: iport = %p, state = 0x%x\n", 70 __func__, iport, status); 71 72 /* XXX pointless lock */ 73 spin_lock_irqsave(&iport->state_lock, flags); 74 iport->status = status; 75 spin_unlock_irqrestore(&iport->state_lock, flags); 76} 77 |
76void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index) | 78/* 79 * This function will indicate which protocols are supported by this port. 80 * @sci_port: a handle corresponding to the SAS port for which to return the 81 * supported protocols. 82 * @protocols: This parameter specifies a pointer to a data structure 83 * which the core will copy the protocol values for the port from the 84 * transmit_identification register. 85 */ 86static void 87scic_sds_port_get_protocols(struct scic_sds_port *sci_port, 88 struct scic_phy_proto *protocols) |
77{ | 89{ |
78 INIT_LIST_HEAD(&iport->remote_dev_list); 79 INIT_LIST_HEAD(&iport->domain_dev_list); 80 spin_lock_init(&iport->state_lock); 81 init_completion(&iport->start_complete); 82 iport->isci_host = ihost; 83 isci_port_change_state(iport, isci_freed); | 90 u8 index; 91 92 protocols->all = 0; 93 94 for (index = 0; index < SCI_MAX_PHYS; index++) { 95 if (sci_port->phy_table[index] != NULL) { 96 scic_sds_phy_get_protocols(sci_port->phy_table[index], 97 protocols); 98 } 99 } |
84} 85 86/** | 100} 101 102/** |
87 * isci_port_get_state() - This function gets the status of the port object. 88 * @isci_port: This parameter points to the isci_port object | 103 * This method requests a list (mask) of the phys contained in the supplied SAS 104 * port. 105 * @sci_port: a handle corresponding to the SAS port for which to return the 106 * phy mask. |
89 * | 107 * |
90 * status of the object as a isci_status enum. | 108 * Return a bit mask indicating which phys are a part of this port. Each bit 109 * corresponds to a phy identifier (e.g. bit 0 = phy id 0). |
91 */ | 110 */ |
92enum isci_status isci_port_get_state( 93 struct isci_port *isci_port) | 111static u32 scic_sds_port_get_phys(struct scic_sds_port *sci_port) |
94{ | 112{ |
95 return isci_port->status; | 113 u32 index; 114 u32 mask; 115 116 mask = 0; 117 118 for (index = 0; index < SCI_MAX_PHYS; index++) { 119 if (sci_port->phy_table[index] != NULL) { 120 mask |= (1 << index); 121 } 122 } 123 124 return mask; |
96} 97 | 125} 126 |
98void isci_port_bc_change_received(struct isci_host *ihost, 99 struct scic_sds_port *sci_port, 100 struct scic_sds_phy *sci_phy) | 127/** 128 * scic_port_get_properties() - This method simply returns the properties 129 * regarding the port, such as: physical index, protocols, sas address, etc. 130 * @port: this parameter specifies the port for which to retrieve the physical 131 * index. 132 * @properties: This parameter specifies the properties structure into which to 133 * copy the requested information. 134 * 135 * Indicate if the user specified a valid port. SCI_SUCCESS This value is 136 * returned if the specified port was valid. SCI_FAILURE_INVALID_PORT This 137 * value is returned if the specified port is not valid. When this value is 138 * returned, no data is copied to the properties output parameter. 139 */ 140static enum sci_status scic_port_get_properties(struct scic_sds_port *port, 141 struct scic_port_properties *prop) |
101{ | 142{ |
102 struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); | 143 if ((port == NULL) || 144 (port->logical_port_index == SCIC_SDS_DUMMY_PORT)) 145 return SCI_FAILURE_INVALID_PORT; |
103 | 146 |
104 dev_dbg(&ihost->pdev->dev, "%s: iphy = %p, sas_phy = %p\n", 105 __func__, iphy, &iphy->sas_phy); | 147 prop->index = port->logical_port_index; 148 prop->phy_mask = scic_sds_port_get_phys(port); 149 scic_sds_port_get_sas_address(port, &prop->local.sas_address); 150 scic_sds_port_get_protocols(port, &prop->local.protocols); 151 scic_sds_port_get_attached_sas_address(port, &prop->remote.sas_address); |
106 | 152 |
107 ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD); 108 scic_port_enable_broadcast_change_notification(sci_port); | 153 return SCI_SUCCESS; |
109} 110 | 154} 155 |
111void isci_port_link_up(struct isci_host *isci_host, 112 struct scic_sds_port *port, 113 struct scic_sds_phy *phy) | 156static void isci_port_link_up(struct isci_host *isci_host, 157 struct scic_sds_port *port, 158 struct scic_sds_phy *phy) |
114{ 115 unsigned long flags; 116 struct scic_port_properties properties; 117 struct isci_phy *isci_phy = sci_phy_to_iphy(phy); 118 struct isci_port *isci_port = sci_port_to_iport(port); 119 unsigned long success = true; 120 121 BUG_ON(isci_phy->isci_port != NULL); --- 57 unchanged lines hidden (view full) --- 179/** 180 * isci_port_link_down() - This function is called by the sci core when a link 181 * becomes inactive. 182 * @isci_host: This parameter specifies the isci host object. 183 * @phy: This parameter specifies the isci phy with the active link. 184 * @port: This parameter specifies the isci port with the active link. 185 * 186 */ | 159{ 160 unsigned long flags; 161 struct scic_port_properties properties; 162 struct isci_phy *isci_phy = sci_phy_to_iphy(phy); 163 struct isci_port *isci_port = sci_port_to_iport(port); 164 unsigned long success = true; 165 166 BUG_ON(isci_phy->isci_port != NULL); --- 57 unchanged lines hidden (view full) --- 224/** 225 * isci_port_link_down() - This function is called by the sci core when a link 226 * becomes inactive. 227 * @isci_host: This parameter specifies the isci host object. 228 * @phy: This parameter specifies the isci phy with the active link. 229 * @port: This parameter specifies the isci port with the active link. 230 * 231 */ |
187void isci_port_link_down(struct isci_host *isci_host, struct isci_phy *isci_phy, 188 struct isci_port *isci_port) | 232static void isci_port_link_down(struct isci_host *isci_host, 233 struct isci_phy *isci_phy, 234 struct isci_port *isci_port) |
189{ 190 struct isci_remote_device *isci_device; 191 192 dev_dbg(&isci_host->pdev->dev, 193 "%s: isci_port = %p\n", __func__, isci_port); 194 195 if (isci_port) { 196 --- 29 unchanged lines hidden (view full) --- 226 isci_phy->isci_port = NULL; 227 228 dev_dbg(&isci_host->pdev->dev, 229 "%s: isci_port = %p - Done\n", __func__, isci_port); 230} 231 232 233/** | 235{ 236 struct isci_remote_device *isci_device; 237 238 dev_dbg(&isci_host->pdev->dev, 239 "%s: isci_port = %p\n", __func__, isci_port); 240 241 if (isci_port) { 242 --- 29 unchanged lines hidden (view full) --- 272 isci_phy->isci_port = NULL; 273 274 dev_dbg(&isci_host->pdev->dev, 275 "%s: isci_port = %p - Done\n", __func__, isci_port); 276} 277 278 279/** |
234 * isci_port_deformed() - This function is called by libsas when a port becomes 235 * inactive. 236 * @phy: This parameter specifies the libsas phy with the inactive port. 237 * 238 */ 239void isci_port_deformed( 240 struct asd_sas_phy *phy) 241{ 242 pr_debug("%s: sas_phy = %p\n", __func__, phy); 243} 244 245/** 246 * isci_port_formed() - This function is called by libsas when a port becomes 247 * active. 248 * @phy: This parameter specifies the libsas phy with the active port. 249 * 250 */ 251void isci_port_formed( 252 struct asd_sas_phy *phy) 253{ 254 pr_debug("%s: sas_phy = %p, sas_port = %p\n", __func__, phy, phy->port); 255} 256 257/** | |
258 * isci_port_ready() - This function is called by the sci core when a link 259 * becomes ready. 260 * @isci_host: This parameter specifies the isci host object. 261 * @port: This parameter specifies the sci port with the active link. 262 * 263 */ | 280 * isci_port_ready() - This function is called by the sci core when a link 281 * becomes ready. 282 * @isci_host: This parameter specifies the isci host object. 283 * @port: This parameter specifies the sci port with the active link. 284 * 285 */ |
264void isci_port_ready(struct isci_host *isci_host, struct isci_port *isci_port) | 286static void isci_port_ready(struct isci_host *isci_host, struct isci_port *isci_port) |
265{ 266 dev_dbg(&isci_host->pdev->dev, 267 "%s: isci_port = %p\n", __func__, isci_port); 268 269 complete_all(&isci_port->start_complete); 270 isci_port_change_state(isci_port, isci_ready); 271 return; 272} 273 274/** 275 * isci_port_not_ready() - This function is called by the sci core when a link 276 * is not ready. All remote devices on this link will be removed if they are 277 * in the stopping state. 278 * @isci_host: This parameter specifies the isci host object. 279 * @port: This parameter specifies the sci port with the active link. 280 * 281 */ | 287{ 288 dev_dbg(&isci_host->pdev->dev, 289 "%s: isci_port = %p\n", __func__, isci_port); 290 291 complete_all(&isci_port->start_complete); 292 isci_port_change_state(isci_port, isci_ready); 293 return; 294} 295 296/** 297 * isci_port_not_ready() - This function is called by the sci core when a link 298 * is not ready. All remote devices on this link will be removed if they are 299 * in the stopping state. 300 * @isci_host: This parameter specifies the isci host object. 301 * @port: This parameter specifies the sci port with the active link. 302 * 303 */ |
282void isci_port_not_ready(struct isci_host *isci_host, struct isci_port *isci_port) | 304static void isci_port_not_ready(struct isci_host *isci_host, struct isci_port *isci_port) |
283{ 284 dev_dbg(&isci_host->pdev->dev, 285 "%s: isci_port = %p\n", __func__, isci_port); 286} 287 | 305{ 306 dev_dbg(&isci_host->pdev->dev, 307 "%s: isci_port = %p\n", __func__, isci_port); 308} 309 |
310static void isci_port_stop_complete(struct scic_sds_controller *scic, 311 struct scic_sds_port *sci_port, 312 enum sci_status completion_status) 313{ 314 dev_dbg(&scic_to_ihost(scic)->pdev->dev, "Port stop complete\n"); 315} 316 |
|
288/** 289 * isci_port_hard_reset_complete() - This function is called by the sci core 290 * when the hard reset complete notification has been received. 291 * @port: This parameter specifies the sci port with the active link. 292 * @completion_status: This parameter specifies the core status for the reset 293 * process. 294 * 295 */ | 317/** 318 * isci_port_hard_reset_complete() - This function is called by the sci core 319 * when the hard reset complete notification has been received. 320 * @port: This parameter specifies the sci port with the active link. 321 * @completion_status: This parameter specifies the core status for the reset 322 * process. 323 * 324 */ |
296void isci_port_hard_reset_complete(struct isci_port *isci_port, 297 enum sci_status completion_status) | 325static void isci_port_hard_reset_complete(struct isci_port *isci_port, 326 enum sci_status completion_status) |
298{ 299 dev_dbg(&isci_port->isci_host->pdev->dev, 300 "%s: isci_port = %p, completion_status=%x\n", 301 __func__, isci_port, completion_status); 302 303 /* Save the status of the hard reset from the port. */ 304 isci_port->hard_reset_status = completion_status; 305 306 complete_all(&isci_port->hard_reset_complete); 307} 308 | 327{ 328 dev_dbg(&isci_port->isci_host->pdev->dev, 329 "%s: isci_port = %p, completion_status=%x\n", 330 __func__, isci_port, completion_status); 331 332 /* Save the status of the hard reset from the port. */ 333 isci_port->hard_reset_status = completion_status; 334 335 complete_all(&isci_port->hard_reset_complete); 336} 337 |
338/* This method will return a true value if the specified phy can be assigned to 339 * this port The following is a list of phys for each port that are allowed: - 340 * Port 0 - 3 2 1 0 - Port 1 - 1 - Port 2 - 3 2 - Port 3 - 3 This method 341 * doesn't preclude all configurations. It merely ensures that a phy is part 342 * of the allowable set of phy identifiers for that port. For example, one 343 * could assign phy 3 to port 0 and no other phys. Please refer to 344 * scic_sds_port_is_phy_mask_valid() for information regarding whether the 345 * phy_mask for a port can be supported. bool true if this is a valid phy 346 * assignment for the port false if this is not a valid phy assignment for the 347 * port 348 */ 349bool scic_sds_port_is_valid_phy_assignment(struct scic_sds_port *sci_port, 350 u32 phy_index) 351{ 352 /* Initialize to invalid value. */ 353 u32 existing_phy_index = SCI_MAX_PHYS; 354 u32 index; 355 356 if ((sci_port->physical_port_index == 1) && (phy_index != 1)) { 357 return false; 358 } 359 360 if (sci_port->physical_port_index == 3 && phy_index != 3) { 361 return false; 362 } 363 364 if ( 365 (sci_port->physical_port_index == 2) 366 && ((phy_index == 0) || (phy_index == 1)) 367 ) { 368 return false; 369 } 370 371 for (index = 0; index < SCI_MAX_PHYS; index++) { 372 if ((sci_port->phy_table[index] != NULL) 373 && (index != phy_index)) { 374 existing_phy_index = index; 375 } 376 } 377 378 /* 379 * Ensure that all of the phys in the port are capable of 380 * operating at the same maximum link rate. */ 381 if ( 382 (existing_phy_index < SCI_MAX_PHYS) 383 && (sci_port->owning_controller->user_parameters.sds1.phys[ 384 phy_index].max_speed_generation != 385 sci_port->owning_controller->user_parameters.sds1.phys[ 386 existing_phy_index].max_speed_generation) 387 ) 388 return false; 389 390 return true; 391} 392 393/** 394 * 395 * @sci_port: This is the port object for which to determine if the phy mask 396 * can be supported. 397 * 398 * This method will return a true value if the port's phy mask can be supported 399 * by the SCU. The following is a list of valid PHY mask configurations for 400 * each port: - Port 0 - [[3 2] 1] 0 - Port 1 - [1] - Port 2 - [[3] 2] 401 * - Port 3 - [3] This method returns a boolean indication specifying if the 402 * phy mask can be supported. true if this is a valid phy assignment for the 403 * port false if this is not a valid phy assignment for the port 404 */ 405static bool scic_sds_port_is_phy_mask_valid( 406 struct scic_sds_port *sci_port, 407 u32 phy_mask) 408{ 409 if (sci_port->physical_port_index == 0) { 410 if (((phy_mask & 0x0F) == 0x0F) 411 || ((phy_mask & 0x03) == 0x03) 412 || ((phy_mask & 0x01) == 0x01) 413 || (phy_mask == 0)) 414 return true; 415 } else if (sci_port->physical_port_index == 1) { 416 if (((phy_mask & 0x02) == 0x02) 417 || (phy_mask == 0)) 418 return true; 419 } else if (sci_port->physical_port_index == 2) { 420 if (((phy_mask & 0x0C) == 0x0C) 421 || ((phy_mask & 0x04) == 0x04) 422 || (phy_mask == 0)) 423 return true; 424 } else if (sci_port->physical_port_index == 3) { 425 if (((phy_mask & 0x08) == 0x08) 426 || (phy_mask == 0)) 427 return true; 428 } 429 430 return false; 431} 432 433/** 434 * 435 * @sci_port: This parameter specifies the port from which to return a 436 * connected phy. 437 * 438 * This method retrieves a currently active (i.e. connected) phy contained in 439 * the port. Currently, the lowest order phy that is connected is returned. 440 * This method returns a pointer to a SCIS_SDS_PHY object. NULL This value is 441 * returned if there are no currently active (i.e. connected to a remote end 442 * point) phys contained in the port. All other values specify a struct scic_sds_phy 443 * object that is active in the port. 444 */ 445static struct scic_sds_phy *scic_sds_port_get_a_connected_phy( 446 struct scic_sds_port *sci_port 447 ) { 448 u32 index; 449 struct scic_sds_phy *phy; 450 451 for (index = 0; index < SCI_MAX_PHYS; index++) { 452 /* 453 * Ensure that the phy is both part of the port and currently 454 * connected to the remote end-point. */ 455 phy = sci_port->phy_table[index]; 456 if ( 457 (phy != NULL) 458 && scic_sds_port_active_phy(sci_port, phy) 459 ) { 460 return phy; 461 } 462 } 463 464 return NULL; 465} 466 467/** 468 * scic_sds_port_set_phy() - 469 * @out]: port The port object to which the phy assignement is being made. 470 * @out]: phy The phy which is being assigned to the port. 471 * 472 * This method attempts to make the assignment of the phy to the port. If 473 * successful the phy is assigned to the ports phy table. bool true if the phy 474 * assignment can be made. false if the phy assignement can not be made. This 475 * is a functional test that only fails if the phy is currently assigned to a 476 * different port. 477 */ 478static enum sci_status scic_sds_port_set_phy( 479 struct scic_sds_port *port, 480 struct scic_sds_phy *phy) 481{ 482 /* 483 * Check to see if we can add this phy to a port 484 * that means that the phy is not part of a port and that the port does 485 * not already have a phy assinged to the phy index. */ 486 if ( 487 (port->phy_table[phy->phy_index] == NULL) 488 && (scic_sds_phy_get_port(phy) == NULL) 489 && scic_sds_port_is_valid_phy_assignment(port, phy->phy_index) 490 ) { 491 /* 492 * Phy is being added in the stopped state so we are in MPC mode 493 * make logical port index = physical port index */ 494 port->logical_port_index = port->physical_port_index; 495 port->phy_table[phy->phy_index] = phy; 496 scic_sds_phy_set_port(phy, port); 497 498 return SCI_SUCCESS; 499 } 500 501 return SCI_FAILURE; 502} 503 504/** 505 * scic_sds_port_clear_phy() - 506 * @out]: port The port from which the phy is being cleared. 507 * @out]: phy The phy being cleared from the port. 508 * 509 * This method will clear the phy assigned to this port. This method fails if 510 * this phy is not currently assinged to this port. bool true if the phy is 511 * removed from the port. false if this phy is not assined to this port. 512 */ 513static enum sci_status scic_sds_port_clear_phy( 514 struct scic_sds_port *port, 515 struct scic_sds_phy *phy) 516{ 517 /* Make sure that this phy is part of this port */ 518 if (port->phy_table[phy->phy_index] == phy && 519 scic_sds_phy_get_port(phy) == port) { 520 struct scic_sds_controller *scic = port->owning_controller; 521 struct isci_host *ihost = scic_to_ihost(scic); 522 523 /* Yep it is assigned to this port so remove it */ 524 scic_sds_phy_set_port(phy, &ihost->ports[SCI_MAX_PORTS].sci); 525 port->phy_table[phy->phy_index] = NULL; 526 return SCI_SUCCESS; 527 } 528 529 return SCI_FAILURE; 530} 531 532/** 533 * scic_sds_port_add_phy() - 534 * @sci_port: This parameter specifies the port in which the phy will be added. 535 * @sci_phy: This parameter is the phy which is to be added to the port. 536 * 537 * This method will add a PHY to the selected port. This method returns an 538 * enum sci_status. SCI_SUCCESS the phy has been added to the port. Any other status 539 * is failre to add the phy to the port. 540 */ 541enum sci_status scic_sds_port_add_phy( 542 struct scic_sds_port *sci_port, 543 struct scic_sds_phy *sci_phy) 544{ 545 return sci_port->state_handlers->add_phy_handler( 546 sci_port, sci_phy); 547} 548 549 550/** 551 * scic_sds_port_remove_phy() - 552 * @sci_port: This parameter specifies the port in which the phy will be added. 553 * @sci_phy: This parameter is the phy which is to be added to the port. 554 * 555 * This method will remove the PHY from the selected PORT. This method returns 556 * an enum sci_status. SCI_SUCCESS the phy has been removed from the port. Any other 557 * status is failre to add the phy to the port. 558 */ 559enum sci_status scic_sds_port_remove_phy( 560 struct scic_sds_port *sci_port, 561 struct scic_sds_phy *sci_phy) 562{ 563 return sci_port->state_handlers->remove_phy_handler( 564 sci_port, sci_phy); 565} 566 567/** 568 * This method requests the SAS address for the supplied SAS port from the SCI 569 * implementation. 570 * @sci_port: a handle corresponding to the SAS port for which to return the 571 * SAS address. 572 * @sas_address: This parameter specifies a pointer to a SAS address structure 573 * into which the core will copy the SAS address for the port. 574 * 575 */ 576void scic_sds_port_get_sas_address( 577 struct scic_sds_port *sci_port, 578 struct sci_sas_address *sas_address) 579{ 580 u32 index; 581 582 sas_address->high = 0; 583 sas_address->low = 0; 584 585 for (index = 0; index < SCI_MAX_PHYS; index++) { 586 if (sci_port->phy_table[index] != NULL) { 587 scic_sds_phy_get_sas_address(sci_port->phy_table[index], sas_address); 588 } 589 } 590} 591 592/* 593 * This function requests the SAS address for the device directly attached to 594 * this SAS port. 595 * @sci_port: a handle corresponding to the SAS port for which to return the 596 * SAS address. 597 * @sas_address: This parameter specifies a pointer to a SAS address structure 598 * into which the core will copy the SAS address for the device directly 599 * attached to the port. 600 * 601 */ 602void scic_sds_port_get_attached_sas_address( 603 struct scic_sds_port *sci_port, 604 struct sci_sas_address *sas_address) 605{ 606 struct scic_sds_phy *sci_phy; 607 608 /* 609 * Ensure that the phy is both part of the port and currently 610 * connected to the remote end-point. 611 */ 612 sci_phy = scic_sds_port_get_a_connected_phy(sci_port); 613 if (sci_phy) { 614 if (sci_phy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA) { 615 scic_sds_phy_get_attached_sas_address(sci_phy, 616 sas_address); 617 } else { 618 scic_sds_phy_get_sas_address(sci_phy, sas_address); 619 sas_address->low += sci_phy->phy_index; 620 } 621 } else { 622 sas_address->high = 0; 623 sas_address->low = 0; 624 } 625} 626 627/** 628 * scic_sds_port_construct_dummy_rnc() - create dummy rnc for si workaround 629 * 630 * @sci_port: logical port on which we need to create the remote node context 631 * @rni: remote node index for this remote node context. 632 * 633 * This routine will construct a dummy remote node context data structure 634 * This structure will be posted to the hardware to work around a scheduler 635 * error in the hardware. 636 */ 637static void scic_sds_port_construct_dummy_rnc(struct scic_sds_port *sci_port, u16 rni) 638{ 639 union scu_remote_node_context *rnc; 640 641 rnc = &sci_port->owning_controller->remote_node_context_table[rni]; 642 643 memset(rnc, 0, sizeof(union scu_remote_node_context)); 644 645 rnc->ssp.remote_sas_address_hi = 0; 646 rnc->ssp.remote_sas_address_lo = 0; 647 648 rnc->ssp.remote_node_index = rni; 649 rnc->ssp.remote_node_port_width = 1; 650 rnc->ssp.logical_port_index = sci_port->physical_port_index; 651 652 rnc->ssp.nexus_loss_timer_enable = false; 653 rnc->ssp.check_bit = false; 654 rnc->ssp.is_valid = true; 655 rnc->ssp.is_remote_node_context = true; 656 rnc->ssp.function_number = 0; 657 rnc->ssp.arbitration_wait_time = 0; 658} 659 660/** 661 * scic_sds_port_construct_dummy_task() - create dummy task for si workaround 662 * @sci_port The logical port on which we need to create the 663 * remote node context. 664 * context. 665 * @tci The remote node index for this remote node context. 666 * 667 * This routine will construct a dummy task context data structure. This 668 * structure will be posted to the hardwre to work around a scheduler error 669 * in the hardware. 670 * 671 */ 672static void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tci) 673{ 674 struct scu_task_context *task_context; 675 676 task_context = scic_sds_controller_get_task_context_buffer(sci_port->owning_controller, tci); 677 678 memset(task_context, 0, sizeof(struct scu_task_context)); 679 680 task_context->abort = 0; 681 task_context->priority = 0; 682 task_context->initiator_request = 1; 683 task_context->connection_rate = 1; 684 task_context->protocol_engine_index = 0; 685 task_context->logical_port_index = sci_port->physical_port_index; 686 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP; 687 task_context->task_index = scic_sds_io_tag_get_index(tci); 688 task_context->valid = SCU_TASK_CONTEXT_VALID; 689 task_context->context_type = SCU_TASK_CONTEXT_TYPE; 690 691 task_context->remote_node_index = sci_port->reserved_rni; 692 task_context->command_code = 0; 693 694 task_context->link_layer_control = 0; 695 task_context->do_not_dma_ssp_good_response = 1; 696 task_context->strict_ordering = 0; 697 task_context->control_frame = 0; 698 task_context->timeout_enable = 0; 699 task_context->block_guard_enable = 0; 700 701 task_context->address_modifier = 0; 702 703 task_context->task_phase = 0x01; 704} 705 706static void scic_sds_port_destroy_dummy_resources(struct scic_sds_port *sci_port) 707{ 708 struct scic_sds_controller *scic = sci_port->owning_controller; 709 710 if (sci_port->reserved_tci != SCU_DUMMY_INDEX) 711 scic_controller_free_io_tag(scic, sci_port->reserved_tci); 712 713 if (sci_port->reserved_rni != SCU_DUMMY_INDEX) 714 scic_sds_remote_node_table_release_remote_node_index(&scic->available_remote_nodes, 715 1, sci_port->reserved_rni); 716 717 sci_port->reserved_rni = SCU_DUMMY_INDEX; 718 sci_port->reserved_tci = SCU_DUMMY_INDEX; 719} 720 721/** 722 * This method performs initialization of the supplied port. Initialization 723 * includes: - state machine initialization - member variable initialization 724 * - configuring the phy_mask 725 * @sci_port: 726 * @transport_layer_registers: 727 * @port_task_scheduler_registers: 728 * @port_configuration_regsiter: 729 * 730 * enum sci_status SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION This value is returned 731 * if the phy being added to the port 732 */ 733enum sci_status scic_sds_port_initialize( 734 struct scic_sds_port *sci_port, 735 void __iomem *port_task_scheduler_registers, 736 void __iomem *port_configuration_regsiter, 737 void __iomem *viit_registers) 738{ 739 sci_port->port_task_scheduler_registers = port_task_scheduler_registers; 740 sci_port->port_pe_configuration_register = port_configuration_regsiter; 741 sci_port->viit_registers = viit_registers; 742 743 return SCI_SUCCESS; 744} 745 746/** 747 * scic_port_hard_reset() - perform port hard reset 748 * @port: a handle corresponding to the SAS port to be hard reset. 749 * @reset_timeout: This parameter specifies the number of milliseconds in which 750 * the port reset operation should complete. 751 * 752 * The SCI User callback in scic_user_callbacks_t will only be called once for 753 * each phy in the SAS Port at completion of the hard reset sequence. Return a 754 * status indicating whether the hard reset started successfully. SCI_SUCCESS 755 * This value is returned if the hard reset operation started successfully. 756 */ 757static enum sci_status scic_port_hard_reset(struct scic_sds_port *port, 758 u32 reset_timeout) 759{ 760 return port->state_handlers->reset_handler( 761 port, reset_timeout); 762} 763 764/** 765 * This method assigns the direct attached device ID for this port. 766 * 767 * @param[in] sci_port The port for which the direct attached device id is to 768 * be assigned. 769 * @param[in] device_id The direct attached device ID to assign to the port. 770 * This will be the RNi for the device 771 */ 772void scic_sds_port_setup_transports( 773 struct scic_sds_port *sci_port, 774 u32 device_id) 775{ 776 u8 index; 777 778 for (index = 0; index < SCI_MAX_PHYS; index++) { 779 if (sci_port->active_phy_mask & (1 << index)) 780 scic_sds_phy_setup_transport(sci_port->phy_table[index], device_id); 781 } 782} 783 784/** 785 * 786 * @sci_port: This is the port on which the phy should be enabled. 787 * @sci_phy: This is the specific phy which to enable. 788 * @do_notify_user: This parameter specifies whether to inform the user (via 789 * scic_cb_port_link_up()) as to the fact that a new phy as become ready. 790 * 791 * This function will activate the phy in the port. 792 * Activation includes: - adding 793 * the phy to the port - enabling the Protocol Engine in the silicon. - 794 * notifying the user that the link is up. none 795 */ 796static void scic_sds_port_activate_phy(struct scic_sds_port *sci_port, 797 struct scic_sds_phy *sci_phy, 798 bool do_notify_user) 799{ 800 struct scic_sds_controller *scic = sci_port->owning_controller; 801 struct isci_host *ihost = scic_to_ihost(scic); 802 803 if (sci_phy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA) 804 scic_sds_phy_resume(sci_phy); 805 806 sci_port->active_phy_mask |= 1 << sci_phy->phy_index; 807 808 scic_sds_controller_clear_invalid_phy(scic, sci_phy); 809 810 if (do_notify_user == true) 811 isci_port_link_up(ihost, sci_port, sci_phy); 812} 813 814void scic_sds_port_deactivate_phy(struct scic_sds_port *sci_port, 815 struct scic_sds_phy *sci_phy, 816 bool do_notify_user) 817{ 818 struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port); 819 struct isci_port *iport = sci_port_to_iport(sci_port); 820 struct isci_host *ihost = scic_to_ihost(scic); 821 struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); 822 823 sci_port->active_phy_mask &= ~(1 << sci_phy->phy_index); 824 825 sci_phy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN; 826 827 /* Re-assign the phy back to the LP as if it were a narrow port */ 828 writel(sci_phy->phy_index, 829 &sci_port->port_pe_configuration_register[sci_phy->phy_index]); 830 831 if (do_notify_user == true) 832 isci_port_link_down(ihost, iphy, iport); 833} 834 835/** 836 * 837 * @sci_port: This is the port on which the phy should be disabled. 838 * @sci_phy: This is the specific phy which to disabled. 839 * 840 * This function will disable the phy and report that the phy is not valid for 841 * this port object. None 842 */ 843static void scic_sds_port_invalid_link_up(struct scic_sds_port *sci_port, 844 struct scic_sds_phy *sci_phy) 845{ 846 struct scic_sds_controller *scic = sci_port->owning_controller; 847 848 /* 849 * Check to see if we have alreay reported this link as bad and if 850 * not go ahead and tell the SCI_USER that we have discovered an 851 * invalid link. 852 */ 853 if ((scic->invalid_phy_mask & (1 << sci_phy->phy_index)) == 0) { 854 scic_sds_controller_set_invalid_phy(scic, sci_phy); 855 dev_warn(&scic_to_ihost(scic)->pdev->dev, "Invalid link up!\n"); 856 } 857} 858 859/** 860 * scic_sds_port_general_link_up_handler - phy can be assigned to port? 861 * @sci_port: scic_sds_port object for which has a phy that has gone link up. 862 * @sci_phy: This is the struct scic_sds_phy object that has gone link up. 863 * @do_notify_user: This parameter specifies whether to inform the user (via 864 * scic_cb_port_link_up()) as to the fact that a new phy as become ready. 865 * 866 * Determine if this phy can be assigned to this 867 * port . If the phy is not a valid PHY for 868 * this port then the function will notify the user. A PHY can only be 869 * part of a port if it's attached SAS ADDRESS is the same as all other PHYs in 870 * the same port. none 871 */ 872static void scic_sds_port_general_link_up_handler(struct scic_sds_port *sci_port, 873 struct scic_sds_phy *sci_phy, 874 bool do_notify_user) 875{ 876 struct sci_sas_address port_sas_address; 877 struct sci_sas_address phy_sas_address; 878 879 scic_sds_port_get_attached_sas_address(sci_port, &port_sas_address); 880 scic_sds_phy_get_attached_sas_address(sci_phy, &phy_sas_address); 881 882 /* If the SAS address of the new phy matches the SAS address of 883 * other phys in the port OR this is the first phy in the port, 884 * then activate the phy and allow it to be used for operations 885 * in this port. 886 */ 887 if ((phy_sas_address.high == port_sas_address.high && 888 phy_sas_address.low == port_sas_address.low) || 889 sci_port->active_phy_mask == 0) { 890 struct sci_base_state_machine *sm = &sci_port->state_machine; 891 892 scic_sds_port_activate_phy(sci_port, sci_phy, do_notify_user); 893 if (sm->current_state_id == SCI_BASE_PORT_STATE_RESETTING) 894 sci_base_state_machine_change_state(sm, SCI_BASE_PORT_STATE_READY); 895 } else 896 scic_sds_port_invalid_link_up(sci_port, sci_phy); 897} 898 899 900 901/** 902 * This method returns false if the port only has a single phy object assigned. 903 * If there are no phys or more than one phy then the method will return 904 * true. 905 * @sci_port: The port for which the wide port condition is to be checked. 906 * 907 * bool true Is returned if this is a wide ported port. false Is returned if 908 * this is a narrow port. 909 */ 910static bool scic_sds_port_is_wide(struct scic_sds_port *sci_port) 911{ 912 u32 index; 913 u32 phy_count = 0; 914 915 for (index = 0; index < SCI_MAX_PHYS; index++) { 916 if (sci_port->phy_table[index] != NULL) { 917 phy_count++; 918 } 919 } 920 921 return phy_count != 1; 922} 923 924/** 925 * This method is called by the PHY object when the link is detected. if the 926 * port wants the PHY to continue on to the link up state then the port 927 * layer must return true. If the port object returns false the phy object 928 * must halt its attempt to go link up. 929 * @sci_port: The port associated with the phy object. 930 * @sci_phy: The phy object that is trying to go link up. 931 * 932 * true if the phy object can continue to the link up condition. true Is 933 * returned if this phy can continue to the ready state. false Is returned if 934 * can not continue on to the ready state. This notification is in place for 935 * wide ports and direct attached phys. Since there are no wide ported SATA 936 * devices this could become an invalid port configuration. 937 */ 938bool scic_sds_port_link_detected( 939 struct scic_sds_port *sci_port, 940 struct scic_sds_phy *sci_phy) 941{ 942 if ((sci_port->logical_port_index != SCIC_SDS_DUMMY_PORT) && 943 (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) && 944 scic_sds_port_is_wide(sci_port)) { 945 scic_sds_port_invalid_link_up(sci_port, sci_phy); 946 947 return false; 948 } 949 950 return true; 951} 952 953/** 954 * This method is the entry point for the phy to inform the port that it is now 955 * in a ready state 956 * @sci_port: 957 * 958 * 959 */ 960void scic_sds_port_link_up( 961 struct scic_sds_port *sci_port, 962 struct scic_sds_phy *sci_phy) 963{ 964 sci_phy->is_in_link_training = false; 965 966 sci_port->state_handlers->link_up_handler(sci_port, sci_phy); 967} 968 969/** 970 * This method is the entry point for the phy to inform the port that it is no 971 * longer in a ready state 972 * @sci_port: 973 * 974 * 975 */ 976void scic_sds_port_link_down( 977 struct scic_sds_port *sci_port, 978 struct scic_sds_phy *sci_phy) 979{ 980 sci_port->state_handlers->link_down_handler(sci_port, sci_phy); 981} 982 983/** 984 * This method is called to start an IO request on this port. 985 * @sci_port: 986 * @sci_dev: 987 * @sci_req: 988 * 989 * enum sci_status 990 */ 991enum sci_status scic_sds_port_start_io( 992 struct scic_sds_port *sci_port, 993 struct scic_sds_remote_device *sci_dev, 994 struct scic_sds_request *sci_req) 995{ 996 return sci_port->state_handlers->start_io_handler( 997 sci_port, sci_dev, sci_req); 998} 999 1000/** 1001 * This method is called to complete an IO request to the port. 1002 * @sci_port: 1003 * @sci_dev: 1004 * @sci_req: 1005 * 1006 * enum sci_status 1007 */ 1008enum sci_status scic_sds_port_complete_io( 1009 struct scic_sds_port *sci_port, 1010 struct scic_sds_remote_device *sci_dev, 1011 struct scic_sds_request *sci_req) 1012{ 1013 return sci_port->state_handlers->complete_io_handler( 1014 sci_port, sci_dev, sci_req); 1015} 1016 1017/** 1018 * This method is provided to timeout requests for port operations. Mostly its 1019 * for the port reset operation. 1020 * 1021 * 1022 */ 1023static void scic_sds_port_timeout_handler(void *port) 1024{ 1025 struct scic_sds_port *sci_port = port; 1026 u32 current_state; 1027 1028 current_state = sci_base_state_machine_get_state( 1029 &sci_port->state_machine); 1030 1031 if (current_state == SCI_BASE_PORT_STATE_RESETTING) { 1032 /* 1033 * if the port is still in the resetting state then the 1034 * timeout fired before the reset completed. 1035 */ 1036 sci_base_state_machine_change_state( 1037 &sci_port->state_machine, 1038 SCI_BASE_PORT_STATE_FAILED); 1039 } else if (current_state == SCI_BASE_PORT_STATE_STOPPED) { 1040 /* 1041 * if the port is stopped then the start request failed 1042 * In this case stay in the stopped state. 1043 */ 1044 dev_err(sciport_to_dev(sci_port), 1045 "%s: SCIC Port 0x%p failed to stop before tiemout.\n", 1046 __func__, 1047 sci_port); 1048 } else if (current_state == SCI_BASE_PORT_STATE_STOPPING) { 1049 /* 1050 * if the port is still stopping then the stop has not 1051 * completed 1052 */ 1053 isci_port_stop_complete( 1054 scic_sds_port_get_controller(sci_port), 1055 sci_port, 1056 SCI_FAILURE_TIMEOUT); 1057 } else { 1058 /* 1059 * The port is in the ready state and we have a timer 1060 * reporting a timeout this should not happen. 1061 */ 1062 dev_err(sciport_to_dev(sci_port), 1063 "%s: SCIC Port 0x%p is processing a timeout operation " 1064 "in state %d.\n", 1065 __func__, 1066 sci_port, 1067 current_state); 1068 } 1069} 1070 1071/* --------------------------------------------------------------------------- */ 1072 1073/** 1074 * This function updates the hardwares VIIT entry for this port. 1075 * 1076 * 1077 */ 1078static void scic_sds_port_update_viit_entry(struct scic_sds_port *sci_port) 1079{ 1080 struct sci_sas_address sas_address; 1081 1082 scic_sds_port_get_sas_address(sci_port, &sas_address); 1083 1084 writel(sas_address.high, 1085 &sci_port->viit_registers->initiator_sas_address_hi); 1086 writel(sas_address.low, 1087 &sci_port->viit_registers->initiator_sas_address_lo); 1088 1089 /* This value get cleared just in case its not already cleared */ 1090 writel(0, &sci_port->viit_registers->reserved); 1091 1092 /* We are required to update the status register last */ 1093 writel(SCU_VIIT_ENTRY_ID_VIIT | 1094 SCU_VIIT_IPPT_INITIATOR | 1095 ((1 << sci_port->physical_port_index) << SCU_VIIT_ENTRY_LPVIE_SHIFT) | 1096 SCU_VIIT_STATUS_ALL_VALID, 1097 &sci_port->viit_registers->status); 1098} 1099 1100/** 1101 * This method returns the maximum allowed speed for data transfers on this 1102 * port. This maximum allowed speed evaluates to the maximum speed of the 1103 * slowest phy in the port. 1104 * @sci_port: This parameter specifies the port for which to retrieve the 1105 * maximum allowed speed. 1106 * 1107 * This method returns the maximum negotiated speed of the slowest phy in the 1108 * port. 1109 */ 1110enum sas_linkrate scic_sds_port_get_max_allowed_speed( 1111 struct scic_sds_port *sci_port) 1112{ 1113 u16 index; 1114 enum sas_linkrate max_allowed_speed = SAS_LINK_RATE_6_0_GBPS; 1115 struct scic_sds_phy *phy = NULL; 1116 1117 /* 1118 * Loop through all of the phys in this port and find the phy with the 1119 * lowest maximum link rate. */ 1120 for (index = 0; index < SCI_MAX_PHYS; index++) { 1121 phy = sci_port->phy_table[index]; 1122 if ( 1123 (phy != NULL) 1124 && (scic_sds_port_active_phy(sci_port, phy) == true) 1125 && (phy->max_negotiated_speed < max_allowed_speed) 1126 ) 1127 max_allowed_speed = phy->max_negotiated_speed; 1128 } 1129 1130 return max_allowed_speed; 1131} 1132 1133static void scic_port_enable_broadcast_change_notification(struct scic_sds_port *port) 1134{ 1135 struct scic_sds_phy *phy; 1136 u32 register_value; 1137 u8 index; 1138 1139 /* Loop through all of the phys to enable BCN. */ 1140 for (index = 0; index < SCI_MAX_PHYS; index++) { 1141 phy = port->phy_table[index]; 1142 if (phy != NULL) { 1143 register_value = 1144 readl(&phy->link_layer_registers->link_layer_control); 1145 1146 /* clear the bit by writing 1. */ 1147 writel(register_value, 1148 &phy->link_layer_registers->link_layer_control); 1149 } 1150 } 1151} 1152 1153/* 1154 * **************************************************************************** 1155 * * READY SUBSTATE HANDLERS 1156 * **************************************************************************** */ 1157 1158/* 1159 * This method is the general ready state stop handler for the struct scic_sds_port 1160 * object. This function will transition the ready substate machine to its 1161 * final state. enum sci_status SCI_SUCCESS 1162 */ 1163static enum sci_status scic_sds_port_ready_substate_stop_handler( 1164 struct scic_sds_port *port) 1165{ 1166 sci_base_state_machine_change_state( 1167 &port->state_machine, 1168 SCI_BASE_PORT_STATE_STOPPING 1169 ); 1170 1171 return SCI_SUCCESS; 1172} 1173 1174/* 1175 * This method is the general ready substate complete io handler for the 1176 * struct scic_sds_port object. This function decrments the outstanding request count 1177 * for this port object. enum sci_status SCI_SUCCESS 1178 */ 1179static enum sci_status scic_sds_port_ready_substate_complete_io_handler( 1180 struct scic_sds_port *port, 1181 struct scic_sds_remote_device *device, 1182 struct scic_sds_request *io_request) 1183{ 1184 scic_sds_port_decrement_request_count(port); 1185 1186 return SCI_SUCCESS; 1187} 1188 1189static enum sci_status scic_sds_port_ready_substate_add_phy_handler( 1190 struct scic_sds_port *port, 1191 struct scic_sds_phy *phy) 1192{ 1193 enum sci_status status; 1194 1195 status = scic_sds_port_set_phy(port, phy); 1196 1197 if (status == SCI_SUCCESS) { 1198 scic_sds_port_general_link_up_handler(port, phy, true); 1199 1200 port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING; 1201 1202 sci_base_state_machine_change_state( 1203 &port->ready_substate_machine, 1204 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING 1205 ); 1206 } 1207 1208 return status; 1209} 1210 1211 1212static enum sci_status scic_sds_port_ready_substate_remove_phy_handler( 1213 struct scic_sds_port *port, 1214 struct scic_sds_phy *phy) 1215{ 1216 enum sci_status status; 1217 1218 status = scic_sds_port_clear_phy(port, phy); 1219 1220 if (status == SCI_SUCCESS) { 1221 scic_sds_port_deactivate_phy(port, phy, true); 1222 1223 port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING; 1224 1225 sci_base_state_machine_change_state( 1226 &port->ready_substate_machine, 1227 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING 1228 ); 1229 } 1230 1231 return status; 1232} 1233 1234/* 1235 * **************************************************************************** 1236 * * READY SUBSTATE WAITING HANDLERS 1237 * **************************************************************************** */ 1238 1239/** 1240 * 1241 * @sci_port: This is the struct scic_sds_port object that which has a phy that has 1242 * gone link up. 1243 * @sci_phy: This is the struct scic_sds_phy object that has gone link up. 1244 * 1245 * This method is the ready waiting substate link up handler for the 1246 * struct scic_sds_port object. This methos will report the link up condition for 1247 * this port and will transition to the ready operational substate. none 1248 */ 1249static void scic_sds_port_ready_waiting_substate_link_up_handler( 1250 struct scic_sds_port *sci_port, 1251 struct scic_sds_phy *sci_phy) 1252{ 1253 /* 1254 * Since this is the first phy going link up for the port we can just enable 1255 * it and continue. */ 1256 scic_sds_port_activate_phy(sci_port, sci_phy, true); 1257 1258 sci_base_state_machine_change_state( 1259 &sci_port->ready_substate_machine, 1260 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL 1261 ); 1262} 1263 1264/* 1265 * This method is the ready waiting substate start io handler for the 1266 * struct scic_sds_port object. The port object can not accept new requests so the 1267 * request is failed. enum sci_status SCI_FAILURE_INVALID_STATE 1268 */ 1269static enum sci_status scic_sds_port_ready_waiting_substate_start_io_handler( 1270 struct scic_sds_port *port, 1271 struct scic_sds_remote_device *device, 1272 struct scic_sds_request *io_request) 1273{ 1274 return SCI_FAILURE_INVALID_STATE; 1275} 1276 1277/* 1278 * **************************************************************************** 1279 * * READY SUBSTATE OPERATIONAL HANDLERS 1280 * **************************************************************************** */ 1281 1282/* 1283 * This method will casue the port to reset. enum sci_status SCI_SUCCESS 1284 */ 1285static enum 1286sci_status scic_sds_port_ready_operational_substate_reset_handler( 1287 struct scic_sds_port *port, 1288 u32 timeout) 1289{ 1290 enum sci_status status = SCI_FAILURE_INVALID_PHY; 1291 u32 phy_index; 1292 struct scic_sds_phy *selected_phy = NULL; 1293 1294 1295 /* Select a phy on which we can send the hard reset request. */ 1296 for (phy_index = 0; 1297 (phy_index < SCI_MAX_PHYS) && (selected_phy == NULL); 1298 phy_index++) { 1299 selected_phy = port->phy_table[phy_index]; 1300 1301 if ((selected_phy != NULL) && 1302 !scic_sds_port_active_phy(port, selected_phy)) { 1303 /* 1304 * We found a phy but it is not ready select 1305 * different phy 1306 */ 1307 selected_phy = NULL; 1308 } 1309 } 1310 1311 /* If we have a phy then go ahead and start the reset procedure */ 1312 if (selected_phy != NULL) { 1313 status = scic_sds_phy_reset(selected_phy); 1314 1315 if (status == SCI_SUCCESS) { 1316 isci_timer_start(port->timer_handle, timeout); 1317 port->not_ready_reason = 1318 SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED; 1319 1320 sci_base_state_machine_change_state( 1321 &port->state_machine, 1322 SCI_BASE_PORT_STATE_RESETTING); 1323 } 1324 } 1325 1326 return status; 1327} 1328 1329/** 1330 * scic_sds_port_ready_operational_substate_link_up_handler() - 1331 * @sci_port: This is the struct scic_sds_port object that which has a phy that has 1332 * gone link up. 1333 * @sci_phy: This is the struct scic_sds_phy object that has gone link up. 1334 * 1335 * This method is the ready operational substate link up handler for the 1336 * struct scic_sds_port object. This function notifies the SCI User that the phy has 1337 * gone link up. none 1338 */ 1339static void scic_sds_port_ready_operational_substate_link_up_handler( 1340 struct scic_sds_port *sci_port, 1341 struct scic_sds_phy *sci_phy) 1342{ 1343 scic_sds_port_general_link_up_handler(sci_port, sci_phy, true); 1344} 1345 1346/** 1347 * scic_sds_port_ready_operational_substate_link_down_handler() - 1348 * @sci_port: This is the struct scic_sds_port object that which has a phy that has 1349 * gone link down. 1350 * @sci_phy: This is the struct scic_sds_phy object that has gone link down. 1351 * 1352 * This method is the ready operational substate link down handler for the 1353 * struct scic_sds_port object. This function notifies the SCI User that the phy has 1354 * gone link down and if this is the last phy in the port the port will change 1355 * state to the ready waiting substate. none 1356 */ 1357static void scic_sds_port_ready_operational_substate_link_down_handler( 1358 struct scic_sds_port *sci_port, 1359 struct scic_sds_phy *sci_phy) 1360{ 1361 scic_sds_port_deactivate_phy(sci_port, sci_phy, true); 1362 1363 /* 1364 * If there are no active phys left in the port, then transition 1365 * the port to the WAITING state until such time as a phy goes 1366 * link up. */ 1367 if (sci_port->active_phy_mask == 0) 1368 sci_base_state_machine_change_state(&sci_port->ready_substate_machine, 1369 SCIC_SDS_PORT_READY_SUBSTATE_WAITING); 1370} 1371 1372/* 1373 * This method is the ready operational substate start io handler for the 1374 * struct scic_sds_port object. This function incremetns the outstanding request 1375 * count for this port object. enum sci_status SCI_SUCCESS 1376 */ 1377static enum sci_status scic_sds_port_ready_operational_substate_start_io_handler( 1378 struct scic_sds_port *port, 1379 struct scic_sds_remote_device *device, 1380 struct scic_sds_request *io_request) 1381{ 1382 port->started_request_count++; 1383 return SCI_SUCCESS; 1384} 1385 1386/* 1387 * **************************************************************************** 1388 * * READY SUBSTATE OPERATIONAL HANDLERS 1389 * **************************************************************************** */ 1390 1391/* 1392 * This is the default method for a port add phy request. It will report a 1393 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE 1394 */ 1395static enum sci_status scic_sds_port_ready_configuring_substate_add_phy_handler( 1396 struct scic_sds_port *port, 1397 struct scic_sds_phy *phy) 1398{ 1399 enum sci_status status; 1400 1401 status = scic_sds_port_set_phy(port, phy); 1402 1403 if (status == SCI_SUCCESS) { 1404 scic_sds_port_general_link_up_handler(port, phy, true); 1405 1406 /* 1407 * Re-enter the configuring state since this may be the last phy in 1408 * the port. */ 1409 sci_base_state_machine_change_state( 1410 &port->ready_substate_machine, 1411 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING 1412 ); 1413 } 1414 1415 return status; 1416} 1417 1418/* 1419 * This is the default method for a port remove phy request. It will report a 1420 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE 1421 */ 1422static enum sci_status scic_sds_port_ready_configuring_substate_remove_phy_handler( 1423 struct scic_sds_port *port, 1424 struct scic_sds_phy *phy) 1425{ 1426 enum sci_status status; 1427 1428 status = scic_sds_port_clear_phy(port, phy); 1429 1430 if (status == SCI_SUCCESS) { 1431 scic_sds_port_deactivate_phy(port, phy, true); 1432 1433 /* 1434 * Re-enter the configuring state since this may be the last phy in 1435 * the port. */ 1436 sci_base_state_machine_change_state( 1437 &port->ready_substate_machine, 1438 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING 1439 ); 1440 } 1441 1442 return status; 1443} 1444 1445/** 1446 * scic_sds_port_ready_configuring_substate_complete_io_handler() - 1447 * @port: This is the port that is being requested to complete the io request. 1448 * @device: This is the device on which the io is completing. 1449 * 1450 * This method will decrement the outstanding request count for this port. If 1451 * the request count goes to 0 then the port can be reprogrammed with its new 1452 * phy data. 1453 */ 1454static enum sci_status 1455scic_sds_port_ready_configuring_substate_complete_io_handler( 1456 struct scic_sds_port *port, 1457 struct scic_sds_remote_device *device, 1458 struct scic_sds_request *io_request) 1459{ 1460 scic_sds_port_decrement_request_count(port); 1461 1462 if (port->started_request_count == 0) { 1463 sci_base_state_machine_change_state( 1464 &port->ready_substate_machine, 1465 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL 1466 ); 1467 } 1468 1469 return SCI_SUCCESS; 1470} 1471 1472static enum sci_status default_port_handler(struct scic_sds_port *sci_port, 1473 const char *func) 1474{ 1475 dev_warn(sciport_to_dev(sci_port), 1476 "%s: in wrong state: %d\n", func, 1477 sci_base_state_machine_get_state(&sci_port->state_machine)); 1478 return SCI_FAILURE_INVALID_STATE; 1479} 1480 1481static enum sci_status 1482scic_sds_port_default_start_handler(struct scic_sds_port *sci_port) 1483{ 1484 return default_port_handler(sci_port, __func__); 1485} 1486 1487static enum sci_status 1488scic_sds_port_default_stop_handler(struct scic_sds_port *sci_port) 1489{ 1490 return default_port_handler(sci_port, __func__); 1491} 1492 1493static enum sci_status 1494scic_sds_port_default_destruct_handler(struct scic_sds_port *sci_port) 1495{ 1496 return default_port_handler(sci_port, __func__); 1497} 1498 1499static enum sci_status 1500scic_sds_port_default_reset_handler(struct scic_sds_port *sci_port, 1501 u32 timeout) 1502{ 1503 return default_port_handler(sci_port, __func__); 1504} 1505 1506static enum sci_status 1507scic_sds_port_default_add_phy_handler(struct scic_sds_port *sci_port, 1508 struct scic_sds_phy *base_phy) 1509{ 1510 return default_port_handler(sci_port, __func__); 1511} 1512 1513static enum sci_status 1514scic_sds_port_default_remove_phy_handler(struct scic_sds_port *sci_port, 1515 struct scic_sds_phy *base_phy) 1516{ 1517 return default_port_handler(sci_port, __func__); 1518} 1519 1520/* 1521 * This is the default method for a port unsolicited frame request. It will 1522 * report a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE Is it even 1523 * possible to receive an unsolicited frame directed to a port object? It 1524 * seems possible if we implementing virtual functions but until then? 1525 */ 1526static enum sci_status 1527scic_sds_port_default_frame_handler(struct scic_sds_port *sci_port, 1528 u32 frame_index) 1529{ 1530 struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port); 1531 1532 default_port_handler(sci_port, __func__); 1533 scic_sds_controller_release_frame(scic, frame_index); 1534 1535 return SCI_FAILURE_INVALID_STATE; 1536} 1537 1538static enum sci_status scic_sds_port_default_event_handler(struct scic_sds_port *sci_port, 1539 u32 event_code) 1540{ 1541 return default_port_handler(sci_port, __func__); 1542} 1543 1544static void scic_sds_port_default_link_up_handler(struct scic_sds_port *sci_port, 1545 struct scic_sds_phy *sci_phy) 1546{ 1547 default_port_handler(sci_port, __func__); 1548} 1549 1550static void scic_sds_port_default_link_down_handler(struct scic_sds_port *sci_port, 1551 struct scic_sds_phy *sci_phy) 1552{ 1553 default_port_handler(sci_port, __func__); 1554} 1555 1556static enum sci_status scic_sds_port_default_start_io_handler(struct scic_sds_port *sci_port, 1557 struct scic_sds_remote_device *sci_dev, 1558 struct scic_sds_request *sci_req) 1559{ 1560 return default_port_handler(sci_port, __func__); 1561} 1562 1563static enum sci_status scic_sds_port_default_complete_io_handler(struct scic_sds_port *sci_port, 1564 struct scic_sds_remote_device *sci_dev, 1565 struct scic_sds_request *sci_req) 1566{ 1567 return default_port_handler(sci_port, __func__); 1568} 1569 1570 1571 1572static struct scic_sds_port_state_handler 1573scic_sds_port_ready_substate_handler_table[SCIC_SDS_PORT_READY_MAX_SUBSTATES] = { 1574 { 1575 /* SCIC_SDS_PORT_READY_SUBSTATE_WAITING */ 1576 scic_sds_port_default_start_handler, 1577 scic_sds_port_ready_substate_stop_handler, 1578 scic_sds_port_default_destruct_handler, 1579 scic_sds_port_default_reset_handler, 1580 scic_sds_port_ready_substate_add_phy_handler, 1581 scic_sds_port_default_remove_phy_handler, 1582 scic_sds_port_default_frame_handler, 1583 scic_sds_port_default_event_handler, 1584 scic_sds_port_ready_waiting_substate_link_up_handler, 1585 scic_sds_port_default_link_down_handler, 1586 scic_sds_port_ready_waiting_substate_start_io_handler, 1587 scic_sds_port_ready_substate_complete_io_handler, 1588 }, 1589 1590 { 1591 /* SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL */ 1592 scic_sds_port_default_start_handler, 1593 scic_sds_port_ready_substate_stop_handler, 1594 scic_sds_port_default_destruct_handler, 1595 scic_sds_port_ready_operational_substate_reset_handler, 1596 scic_sds_port_ready_substate_add_phy_handler, 1597 scic_sds_port_ready_substate_remove_phy_handler, 1598 scic_sds_port_default_frame_handler, 1599 scic_sds_port_default_event_handler, 1600 scic_sds_port_ready_operational_substate_link_up_handler, 1601 scic_sds_port_ready_operational_substate_link_down_handler, 1602 scic_sds_port_ready_operational_substate_start_io_handler, 1603 scic_sds_port_ready_substate_complete_io_handler, 1604 }, 1605 1606 { 1607 /* SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING */ 1608 scic_sds_port_default_start_handler, 1609 scic_sds_port_ready_substate_stop_handler, 1610 scic_sds_port_default_destruct_handler, 1611 scic_sds_port_default_reset_handler, 1612 scic_sds_port_ready_configuring_substate_add_phy_handler, 1613 scic_sds_port_ready_configuring_substate_remove_phy_handler, 1614 scic_sds_port_default_frame_handler, 1615 scic_sds_port_default_event_handler, 1616 scic_sds_port_default_link_up_handler, 1617 scic_sds_port_default_link_down_handler, 1618 scic_sds_port_default_start_io_handler, 1619 scic_sds_port_ready_configuring_substate_complete_io_handler 1620 } 1621}; 1622 1623/** 1624 * scic_sds_port_set_ready_state_handlers() - 1625 * 1626 * This macro sets the port ready substate handlers. 1627 */ 1628#define scic_sds_port_set_ready_state_handlers(port, state_id) \ 1629 scic_sds_port_set_state_handlers(\ 1630 port, &scic_sds_port_ready_substate_handler_table[(state_id)] \ 1631 ) 1632 1633/* 1634 * ****************************************************************************** 1635 * * PORT STATE PRIVATE METHODS 1636 * ****************************************************************************** */ 1637 1638/** 1639 * 1640 * @sci_port: This is the struct scic_sds_port object to suspend. 1641 * 1642 * This method will susped the port task scheduler for this port object. none 1643 */ 1644static void 1645scic_sds_port_suspend_port_task_scheduler(struct scic_sds_port *port) 1646{ 1647 u32 pts_control_value; 1648 1649 pts_control_value = readl(&port->port_task_scheduler_registers->control); 1650 pts_control_value |= SCU_PTSxCR_GEN_BIT(SUSPEND); 1651 writel(pts_control_value, &port->port_task_scheduler_registers->control); 1652} 1653 1654/** 1655 * scic_sds_port_post_dummy_request() - post dummy/workaround request 1656 * @sci_port: port to post task 1657 * 1658 * Prevent the hardware scheduler from posting new requests to the front 1659 * of the scheduler queue causing a starvation problem for currently 1660 * ongoing requests. 1661 * 1662 */ 1663static void scic_sds_port_post_dummy_request(struct scic_sds_port *sci_port) 1664{ 1665 u32 command; 1666 struct scu_task_context *task_context; 1667 struct scic_sds_controller *scic = sci_port->owning_controller; 1668 u16 tci = sci_port->reserved_tci; 1669 1670 task_context = scic_sds_controller_get_task_context_buffer(scic, tci); 1671 1672 task_context->abort = 0; 1673 1674 command = SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC | 1675 sci_port->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | 1676 tci; 1677 1678 scic_sds_controller_post_request(scic, command); 1679} 1680 1681/** 1682 * This routine will abort the dummy request. This will alow the hardware to 1683 * power down parts of the silicon to save power. 1684 * 1685 * @sci_port: The port on which the task must be aborted. 1686 * 1687 */ 1688static void scic_sds_port_abort_dummy_request(struct scic_sds_port *sci_port) 1689{ 1690 struct scic_sds_controller *scic = sci_port->owning_controller; 1691 u16 tci = sci_port->reserved_tci; 1692 struct scu_task_context *tc; 1693 u32 command; 1694 1695 tc = scic_sds_controller_get_task_context_buffer(scic, tci); 1696 1697 tc->abort = 1; 1698 1699 command = SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT | 1700 sci_port->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | 1701 tci; 1702 1703 scic_sds_controller_post_request(scic, command); 1704} 1705 1706/** 1707 * 1708 * @sci_port: This is the struct scic_sds_port object to resume. 1709 * 1710 * This method will resume the port task scheduler for this port object. none 1711 */ 1712static void 1713scic_sds_port_resume_port_task_scheduler(struct scic_sds_port *port) 1714{ 1715 u32 pts_control_value; 1716 1717 pts_control_value = readl(&port->port_task_scheduler_registers->control); 1718 pts_control_value &= ~SCU_PTSxCR_GEN_BIT(SUSPEND); 1719 writel(pts_control_value, &port->port_task_scheduler_registers->control); 1720} 1721 1722/* 1723 * ****************************************************************************** 1724 * * PORT READY SUBSTATE METHODS 1725 * ****************************************************************************** */ 1726 1727/** 1728 * 1729 * @object: This is the object which is cast to a struct scic_sds_port object. 1730 * 1731 * This method will perform the actions required by the struct scic_sds_port on 1732 * entering the SCIC_SDS_PORT_READY_SUBSTATE_WAITING. This function checks the 1733 * port for any ready phys. If there is at least one phy in a ready state then 1734 * the port transitions to the ready operational substate. none 1735 */ 1736static void scic_sds_port_ready_substate_waiting_enter(void *object) 1737{ 1738 struct scic_sds_port *sci_port = object; 1739 1740 scic_sds_port_set_ready_state_handlers( 1741 sci_port, SCIC_SDS_PORT_READY_SUBSTATE_WAITING 1742 ); 1743 1744 scic_sds_port_suspend_port_task_scheduler(sci_port); 1745 1746 sci_port->not_ready_reason = SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS; 1747 1748 if (sci_port->active_phy_mask != 0) { 1749 /* At least one of the phys on the port is ready */ 1750 sci_base_state_machine_change_state( 1751 &sci_port->ready_substate_machine, 1752 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL 1753 ); 1754 } 1755} 1756 1757/** 1758 * 1759 * @object: This is the object which is cast to a struct scic_sds_port object. 1760 * 1761 * This function will perform the actions required by the struct scic_sds_port 1762 * on entering the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function sets 1763 * the state handlers for the port object, notifies the SCI User that the port 1764 * is ready, and resumes port operations. none 1765 */ 1766static void scic_sds_port_ready_substate_operational_enter(void *object) 1767{ 1768 u32 index; 1769 struct scic_sds_port *sci_port = object; 1770 struct scic_sds_controller *scic = sci_port->owning_controller; 1771 struct isci_host *ihost = scic_to_ihost(scic); 1772 struct isci_port *iport = sci_port_to_iport(sci_port); 1773 1774 scic_sds_port_set_ready_state_handlers( 1775 sci_port, 1776 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL); 1777 1778 isci_port_ready(ihost, iport); 1779 1780 for (index = 0; index < SCI_MAX_PHYS; index++) { 1781 if (sci_port->phy_table[index]) { 1782 writel(sci_port->physical_port_index, 1783 &sci_port->port_pe_configuration_register[ 1784 sci_port->phy_table[index]->phy_index]); 1785 } 1786 } 1787 1788 scic_sds_port_update_viit_entry(sci_port); 1789 1790 scic_sds_port_resume_port_task_scheduler(sci_port); 1791 1792 /* 1793 * Post the dummy task for the port so the hardware can schedule 1794 * io correctly 1795 */ 1796 scic_sds_port_post_dummy_request(sci_port); 1797} 1798 1799/** 1800 * 1801 * @object: This is the object which is cast to a struct scic_sds_port object. 1802 * 1803 * This method will perform the actions required by the struct scic_sds_port on 1804 * exiting the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function reports 1805 * the port not ready and suspends the port task scheduler. none 1806 */ 1807static void scic_sds_port_ready_substate_operational_exit(void *object) 1808{ 1809 struct scic_sds_port *sci_port = object; 1810 struct scic_sds_controller *scic = sci_port->owning_controller; 1811 struct isci_host *ihost = scic_to_ihost(scic); 1812 struct isci_port *iport = sci_port_to_iport(sci_port); 1813 1814 /* 1815 * Kill the dummy task for this port if it has not yet posted 1816 * the hardware will treat this as a NOP and just return abort 1817 * complete. 1818 */ 1819 scic_sds_port_abort_dummy_request(sci_port); 1820 1821 isci_port_not_ready(ihost, iport); 1822} 1823 1824/* 1825 * ****************************************************************************** 1826 * * PORT READY CONFIGURING METHODS 1827 * ****************************************************************************** */ 1828 1829/** 1830 * scic_sds_port_ready_substate_configuring_enter() - 1831 * @object: This is the object which is cast to a struct scic_sds_port object. 1832 * 1833 * This method will perform the actions required by the struct scic_sds_port on 1834 * exiting the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function reports 1835 * the port not ready and suspends the port task scheduler. none 1836 */ 1837static void scic_sds_port_ready_substate_configuring_enter(void *object) 1838{ 1839 struct scic_sds_port *sci_port = object; 1840 struct scic_sds_controller *scic = sci_port->owning_controller; 1841 struct isci_host *ihost = scic_to_ihost(scic); 1842 struct isci_port *iport = sci_port_to_iport(sci_port); 1843 1844 scic_sds_port_set_ready_state_handlers( 1845 sci_port, 1846 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING); 1847 1848 if (sci_port->active_phy_mask == 0) { 1849 isci_port_not_ready(ihost, iport); 1850 1851 sci_base_state_machine_change_state( 1852 &sci_port->ready_substate_machine, 1853 SCIC_SDS_PORT_READY_SUBSTATE_WAITING); 1854 } else if (sci_port->started_request_count == 0) 1855 sci_base_state_machine_change_state( 1856 &sci_port->ready_substate_machine, 1857 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL); 1858} 1859 1860static void scic_sds_port_ready_substate_configuring_exit(void *object) 1861{ 1862 struct scic_sds_port *sci_port = object; 1863 1864 scic_sds_port_suspend_port_task_scheduler(sci_port); 1865} 1866 1867/* --------------------------------------------------------------------------- */ 1868 1869static const struct sci_base_state scic_sds_port_ready_substate_table[] = { 1870 [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = { 1871 .enter_state = scic_sds_port_ready_substate_waiting_enter, 1872 }, 1873 [SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = { 1874 .enter_state = scic_sds_port_ready_substate_operational_enter, 1875 .exit_state = scic_sds_port_ready_substate_operational_exit 1876 }, 1877 [SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = { 1878 .enter_state = scic_sds_port_ready_substate_configuring_enter, 1879 .exit_state = scic_sds_port_ready_substate_configuring_exit 1880 }, 1881}; 1882 1883/** 1884 * 1885 * @port: This is the struct scic_sds_port object on which the io request count will 1886 * be decremented. 1887 * @device: This is the struct scic_sds_remote_device object to which the io request 1888 * is being directed. This parameter is not required to complete this 1889 * operation. 1890 * @io_request: This is the request that is being completed on this port 1891 * object. This parameter is not required to complete this operation. 1892 * 1893 * This is a general complete io request handler for the struct scic_sds_port object. 1894 * enum sci_status SCI_SUCCESS 1895 */ 1896static enum sci_status scic_sds_port_general_complete_io_handler( 1897 struct scic_sds_port *port, 1898 struct scic_sds_remote_device *device, 1899 struct scic_sds_request *io_request) 1900{ 1901 scic_sds_port_decrement_request_count(port); 1902 1903 return SCI_SUCCESS; 1904} 1905 1906/** 1907 * scic_sds_port_stopped_state_start_handler() - stop a port from "started" 1908 * 1909 * @port: This is the struct scic_sds_port object which is cast into a 1910 * struct scic_sds_port object. 1911 * 1912 * This function takes the struct scic_sds_port from a stopped state and 1913 * attempts to start it. To start a port it must have no assiged devices and 1914 * it must have at least one phy assigned to it. If those conditions are 1915 * met then the port can transition to the ready state. 1916 * enum sci_status 1917 * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION 1918 * This struct scic_sds_port object could not be started because the port 1919 * configuration is not valid. 1920 * SCI_SUCCESS 1921 * the start request is successful and the struct scic_sds_port object 1922 * has transitioned to the SCI_BASE_PORT_STATE_READY. 1923 */ 1924static enum sci_status 1925scic_sds_port_stopped_state_start_handler(struct scic_sds_port *sci_port) 1926{ 1927 struct scic_sds_controller *scic = sci_port->owning_controller; 1928 struct isci_host *ihost = scic_to_ihost(scic); 1929 enum sci_status status = SCI_SUCCESS; 1930 u32 phy_mask; 1931 1932 if (sci_port->assigned_device_count > 0) { 1933 /* 1934 * @todo This is a start failure operation because 1935 * there are still devices assigned to this port. 1936 * There must be no devices assigned to a port on a 1937 * start operation. 1938 */ 1939 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; 1940 } 1941 1942 sci_port->timer_handle = 1943 isci_timer_create(ihost, 1944 sci_port, 1945 scic_sds_port_timeout_handler); 1946 1947 if (!sci_port->timer_handle) 1948 return SCI_FAILURE_INSUFFICIENT_RESOURCES; 1949 1950 if (sci_port->reserved_rni == SCU_DUMMY_INDEX) { 1951 u16 rni = scic_sds_remote_node_table_allocate_remote_node( 1952 &scic->available_remote_nodes, 1); 1953 1954 if (rni != SCU_DUMMY_INDEX) 1955 scic_sds_port_construct_dummy_rnc(sci_port, rni); 1956 else 1957 status = SCI_FAILURE_INSUFFICIENT_RESOURCES; 1958 sci_port->reserved_rni = rni; 1959 } 1960 1961 if (sci_port->reserved_tci == SCU_DUMMY_INDEX) { 1962 /* Allocate a TCI and remove the sequence nibble */ 1963 u16 tci = scic_controller_allocate_io_tag(scic); 1964 1965 if (tci != SCU_DUMMY_INDEX) 1966 scic_sds_port_construct_dummy_task(sci_port, tci); 1967 else 1968 status = SCI_FAILURE_INSUFFICIENT_RESOURCES; 1969 sci_port->reserved_tci = tci; 1970 } 1971 1972 if (status == SCI_SUCCESS) { 1973 phy_mask = scic_sds_port_get_phys(sci_port); 1974 1975 /* 1976 * There are one or more phys assigned to this port. Make sure 1977 * the port's phy mask is in fact legal and supported by the 1978 * silicon. 1979 */ 1980 if (scic_sds_port_is_phy_mask_valid(sci_port, phy_mask) == true) { 1981 sci_base_state_machine_change_state( 1982 &sci_port->state_machine, 1983 SCI_BASE_PORT_STATE_READY); 1984 1985 return SCI_SUCCESS; 1986 } else 1987 status = SCI_FAILURE; 1988 } 1989 1990 if (status != SCI_SUCCESS) 1991 scic_sds_port_destroy_dummy_resources(sci_port); 1992 1993 return status; 1994} 1995 1996/* 1997 * This method takes the struct scic_sds_port that is in a stopped state and handles a 1998 * stop request. This function takes no action. enum sci_status SCI_SUCCESS the 1999 * stop request is successful as the struct scic_sds_port object is already stopped. 2000 */ 2001static enum sci_status scic_sds_port_stopped_state_stop_handler( 2002 struct scic_sds_port *port) 2003{ 2004 /* We are already stopped so there is nothing to do here */ 2005 return SCI_SUCCESS; 2006} 2007 2008/* 2009 * This method takes the struct scic_sds_port that is in a stopped state and handles 2010 * the destruct request. The stopped state is the only state in which the 2011 * struct scic_sds_port can be destroyed. This function causes the port object to 2012 * transition to the SCI_BASE_PORT_STATE_FINAL. enum sci_status SCI_SUCCESS 2013 */ 2014static enum sci_status scic_sds_port_stopped_state_destruct_handler( 2015 struct scic_sds_port *port) 2016{ 2017 sci_base_state_machine_stop(&port->state_machine); 2018 2019 return SCI_SUCCESS; 2020} 2021 2022/* 2023 * This method takes the struct scic_sds_port that is in a stopped state and handles 2024 * the add phy request. In MPC mode the only time a phy can be added to a port 2025 * is in the SCI_BASE_PORT_STATE_STOPPED. enum sci_status 2026 * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION is returned when the phy can not 2027 * be added to the port. SCI_SUCCESS if the phy is added to the port. 2028 */ 2029static enum sci_status scic_sds_port_stopped_state_add_phy_handler( 2030 struct scic_sds_port *port, 2031 struct scic_sds_phy *phy) 2032{ 2033 struct sci_sas_address port_sas_address; 2034 2035 /* Read the port assigned SAS Address if there is one */ 2036 scic_sds_port_get_sas_address(port, &port_sas_address); 2037 2038 if (port_sas_address.high != 0 && port_sas_address.low != 0) { 2039 struct sci_sas_address phy_sas_address; 2040 2041 /* 2042 * Make sure that the PHY SAS Address matches the SAS Address 2043 * for this port. */ 2044 scic_sds_phy_get_sas_address(phy, &phy_sas_address); 2045 2046 if ( 2047 (port_sas_address.high != phy_sas_address.high) 2048 || (port_sas_address.low != phy_sas_address.low) 2049 ) { 2050 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; 2051 } 2052 } 2053 2054 return scic_sds_port_set_phy(port, phy); 2055} 2056 2057/* 2058 * This method takes the struct scic_sds_port that is in a stopped state and handles 2059 * the remove phy request. In MPC mode the only time a phy can be removed from 2060 * a port is in the SCI_BASE_PORT_STATE_STOPPED. enum sci_status 2061 * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION is returned when the phy can not 2062 * be added to the port. SCI_SUCCESS if the phy is added to the port. 2063 */ 2064static enum sci_status scic_sds_port_stopped_state_remove_phy_handler( 2065 struct scic_sds_port *port, 2066 struct scic_sds_phy *phy) 2067{ 2068 return scic_sds_port_clear_phy(port, phy); 2069} 2070 2071/* 2072 * **************************************************************************** 2073 * * READY STATE HANDLERS 2074 * **************************************************************************** */ 2075 2076/* 2077 * **************************************************************************** 2078 * * RESETTING STATE HANDLERS 2079 * **************************************************************************** */ 2080 2081/* 2082 * **************************************************************************** 2083 * * STOPPING STATE HANDLERS 2084 * **************************************************************************** */ 2085 2086/* 2087 * This method takes the struct scic_sds_port that is in a stopping state and handles 2088 * the complete io request. Should the request count reach 0 then the port 2089 * object will transition to the stopped state. enum sci_status SCI_SUCCESS 2090 */ 2091static enum sci_status scic_sds_port_stopping_state_complete_io_handler( 2092 struct scic_sds_port *sci_port, 2093 struct scic_sds_remote_device *device, 2094 struct scic_sds_request *io_request) 2095{ 2096 scic_sds_port_decrement_request_count(sci_port); 2097 2098 if (sci_port->started_request_count == 0) { 2099 sci_base_state_machine_change_state(&sci_port->state_machine, 2100 SCI_BASE_PORT_STATE_STOPPED); 2101 } 2102 2103 return SCI_SUCCESS; 2104} 2105 2106/* 2107 * **************************************************************************** 2108 * * RESETTING STATE HANDLERS 2109 * **************************************************************************** */ 2110 2111/** 2112 * 2113 * @port: This is the port object which is being requested to stop. 2114 * 2115 * This method will stop a failed port. This causes a transition to the 2116 * stopping state. enum sci_status SCI_SUCCESS 2117 */ 2118static enum sci_status scic_sds_port_reset_state_stop_handler( 2119 struct scic_sds_port *port) 2120{ 2121 sci_base_state_machine_change_state( 2122 &port->state_machine, 2123 SCI_BASE_PORT_STATE_STOPPING 2124 ); 2125 2126 return SCI_SUCCESS; 2127} 2128 2129/* 2130 * This method will transition a failed port to its ready state. The port 2131 * failed because a hard reset request timed out but at some time later one or 2132 * more phys in the port became ready. enum sci_status SCI_SUCCESS 2133 */ 2134static void scic_sds_port_reset_state_link_up_handler( 2135 struct scic_sds_port *port, 2136 struct scic_sds_phy *phy) 2137{ 2138 /* 2139 * / @todo We should make sure that the phy that has gone link up is the same 2140 * / one on which we sent the reset. It is possible that the phy on 2141 * / which we sent the reset is not the one that has gone link up and we 2142 * / want to make sure that phy being reset comes back. Consider the 2143 * / case where a reset is sent but before the hardware processes the 2144 * / reset it get a link up on the port because of a hot plug event. 2145 * / because of the reset request this phy will go link down almost 2146 * / immediately. */ 2147 2148 /* 2149 * In the resetting state we don't notify the user regarding 2150 * link up and link down notifications. */ 2151 scic_sds_port_general_link_up_handler(port, phy, false); 2152} 2153 2154/* 2155 * This method process link down notifications that occur during a port reset 2156 * operation. Link downs can occur during the reset operation. enum sci_status 2157 * SCI_SUCCESS 2158 */ 2159static void scic_sds_port_reset_state_link_down_handler( 2160 struct scic_sds_port *port, 2161 struct scic_sds_phy *phy) 2162{ 2163 /* 2164 * In the resetting state we don't notify the user regarding 2165 * link up and link down notifications. */ 2166 scic_sds_port_deactivate_phy(port, phy, false); 2167} 2168 2169static struct scic_sds_port_state_handler 2170scic_sds_port_state_handler_table[SCI_BASE_PORT_MAX_STATES] = 2171{ 2172 /* SCI_BASE_PORT_STATE_STOPPED */ 2173 { 2174 scic_sds_port_stopped_state_start_handler, 2175 scic_sds_port_stopped_state_stop_handler, 2176 scic_sds_port_stopped_state_destruct_handler, 2177 scic_sds_port_default_reset_handler, 2178 scic_sds_port_stopped_state_add_phy_handler, 2179 scic_sds_port_stopped_state_remove_phy_handler, 2180 scic_sds_port_default_frame_handler, 2181 scic_sds_port_default_event_handler, 2182 scic_sds_port_default_link_up_handler, 2183 scic_sds_port_default_link_down_handler, 2184 scic_sds_port_default_start_io_handler, 2185 scic_sds_port_default_complete_io_handler 2186 }, 2187 /* SCI_BASE_PORT_STATE_STOPPING */ 2188 { 2189 scic_sds_port_default_start_handler, 2190 scic_sds_port_default_stop_handler, 2191 scic_sds_port_default_destruct_handler, 2192 scic_sds_port_default_reset_handler, 2193 scic_sds_port_default_add_phy_handler, 2194 scic_sds_port_default_remove_phy_handler, 2195 scic_sds_port_default_frame_handler, 2196 scic_sds_port_default_event_handler, 2197 scic_sds_port_default_link_up_handler, 2198 scic_sds_port_default_link_down_handler, 2199 scic_sds_port_default_start_io_handler, 2200 scic_sds_port_stopping_state_complete_io_handler 2201 }, 2202 /* SCI_BASE_PORT_STATE_READY */ 2203 { 2204 scic_sds_port_default_start_handler, 2205 scic_sds_port_default_stop_handler, 2206 scic_sds_port_default_destruct_handler, 2207 scic_sds_port_default_reset_handler, 2208 scic_sds_port_default_add_phy_handler, 2209 scic_sds_port_default_remove_phy_handler, 2210 scic_sds_port_default_frame_handler, 2211 scic_sds_port_default_event_handler, 2212 scic_sds_port_default_link_up_handler, 2213 scic_sds_port_default_link_down_handler, 2214 scic_sds_port_default_start_io_handler, 2215 scic_sds_port_general_complete_io_handler 2216 }, 2217 /* SCI_BASE_PORT_STATE_RESETTING */ 2218 { 2219 scic_sds_port_default_start_handler, 2220 scic_sds_port_reset_state_stop_handler, 2221 scic_sds_port_default_destruct_handler, 2222 scic_sds_port_default_reset_handler, 2223 scic_sds_port_default_add_phy_handler, 2224 scic_sds_port_default_remove_phy_handler, 2225 scic_sds_port_default_frame_handler, 2226 scic_sds_port_default_event_handler, 2227 scic_sds_port_reset_state_link_up_handler, 2228 scic_sds_port_reset_state_link_down_handler, 2229 scic_sds_port_default_start_io_handler, 2230 scic_sds_port_general_complete_io_handler 2231 }, 2232 /* SCI_BASE_PORT_STATE_FAILED */ 2233 { 2234 scic_sds_port_default_start_handler, 2235 scic_sds_port_default_stop_handler, 2236 scic_sds_port_default_destruct_handler, 2237 scic_sds_port_default_reset_handler, 2238 scic_sds_port_default_add_phy_handler, 2239 scic_sds_port_default_remove_phy_handler, 2240 scic_sds_port_default_frame_handler, 2241 scic_sds_port_default_event_handler, 2242 scic_sds_port_default_link_up_handler, 2243 scic_sds_port_default_link_down_handler, 2244 scic_sds_port_default_start_io_handler, 2245 scic_sds_port_general_complete_io_handler 2246 } 2247}; 2248 2249/* 2250 * ****************************************************************************** 2251 * * PORT STATE PRIVATE METHODS 2252 * ****************************************************************************** */ 2253 2254/** 2255 * 2256 * @sci_port: This is the port object which to suspend. 2257 * 2258 * This method will enable the SCU Port Task Scheduler for this port object but 2259 * will leave the port task scheduler in a suspended state. none 2260 */ 2261static void 2262scic_sds_port_enable_port_task_scheduler(struct scic_sds_port *port) 2263{ 2264 u32 pts_control_value; 2265 2266 pts_control_value = readl(&port->port_task_scheduler_registers->control); 2267 pts_control_value |= SCU_PTSxCR_GEN_BIT(ENABLE) | SCU_PTSxCR_GEN_BIT(SUSPEND); 2268 writel(pts_control_value, &port->port_task_scheduler_registers->control); 2269} 2270 2271/** 2272 * 2273 * @sci_port: This is the port object which to resume. 2274 * 2275 * This method will disable the SCU port task scheduler for this port object. 2276 * none 2277 */ 2278static void 2279scic_sds_port_disable_port_task_scheduler(struct scic_sds_port *port) 2280{ 2281 u32 pts_control_value; 2282 2283 pts_control_value = readl(&port->port_task_scheduler_registers->control); 2284 pts_control_value &= 2285 ~(SCU_PTSxCR_GEN_BIT(ENABLE) | SCU_PTSxCR_GEN_BIT(SUSPEND)); 2286 writel(pts_control_value, &port->port_task_scheduler_registers->control); 2287} 2288 2289static void scic_sds_port_post_dummy_remote_node(struct scic_sds_port *sci_port) 2290{ 2291 struct scic_sds_controller *scic = sci_port->owning_controller; 2292 u8 phys_index = sci_port->physical_port_index; 2293 union scu_remote_node_context *rnc; 2294 u16 rni = sci_port->reserved_rni; 2295 u32 command; 2296 2297 rnc = &scic->remote_node_context_table[rni]; 2298 rnc->ssp.is_valid = true; 2299 2300 command = SCU_CONTEXT_COMMAND_POST_RNC_32 | 2301 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni; 2302 2303 scic_sds_controller_post_request(scic, command); 2304 2305 /* ensure hardware has seen the post rnc command and give it 2306 * ample time to act before sending the suspend 2307 */ 2308 readl(&scic->smu_registers->interrupt_status); /* flush */ 2309 udelay(10); 2310 2311 command = SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX | 2312 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni; 2313 2314 scic_sds_controller_post_request(scic, command); 2315} 2316 2317static void scic_sds_port_invalidate_dummy_remote_node(struct scic_sds_port *sci_port) 2318{ 2319 struct scic_sds_controller *scic = sci_port->owning_controller; 2320 u8 phys_index = sci_port->physical_port_index; 2321 union scu_remote_node_context *rnc; 2322 u16 rni = sci_port->reserved_rni; 2323 u32 command; 2324 2325 rnc = &scic->remote_node_context_table[rni]; 2326 2327 rnc->ssp.is_valid = false; 2328 2329 /* ensure the preceding tc abort request has reached the 2330 * controller and give it ample time to act before posting the rnc 2331 * invalidate 2332 */ 2333 readl(&scic->smu_registers->interrupt_status); /* flush */ 2334 udelay(10); 2335 2336 command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE | 2337 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni; 2338 2339 scic_sds_controller_post_request(scic, command); 2340} 2341 2342/* 2343 * ****************************************************************************** 2344 * * PORT STATE METHODS 2345 * ****************************************************************************** */ 2346 2347/** 2348 * 2349 * @object: This is the object which is cast to a struct scic_sds_port object. 2350 * 2351 * This method will perform the actions required by the struct scic_sds_port on 2352 * entering the SCI_BASE_PORT_STATE_STOPPED. This function sets the stopped 2353 * state handlers for the struct scic_sds_port object and disables the port task 2354 * scheduler in the hardware. none 2355 */ 2356static void scic_sds_port_stopped_state_enter(void *object) 2357{ 2358 struct scic_sds_port *sci_port = object; 2359 2360 scic_sds_port_set_base_state_handlers( 2361 sci_port, SCI_BASE_PORT_STATE_STOPPED 2362 ); 2363 2364 if ( 2365 SCI_BASE_PORT_STATE_STOPPING 2366 == sci_port->state_machine.previous_state_id 2367 ) { 2368 /* 2369 * If we enter this state becasuse of a request to stop 2370 * the port then we want to disable the hardwares port 2371 * task scheduler. */ 2372 scic_sds_port_disable_port_task_scheduler(sci_port); 2373 } 2374} 2375 2376/** 2377 * 2378 * @object: This is the object which is cast to a struct scic_sds_port object. 2379 * 2380 * This method will perform the actions required by the struct scic_sds_port on 2381 * exiting the SCI_BASE_STATE_STOPPED. This function enables the SCU hardware 2382 * port task scheduler. none 2383 */ 2384static void scic_sds_port_stopped_state_exit(void *object) 2385{ 2386 struct scic_sds_port *sci_port = object; 2387 2388 /* Enable and suspend the port task scheduler */ 2389 scic_sds_port_enable_port_task_scheduler(sci_port); 2390} 2391 2392/** 2393 * scic_sds_port_ready_state_enter - 2394 * @object: This is the object which is cast to a struct scic_sds_port object. 2395 * 2396 * This method will perform the actions required by the struct scic_sds_port on 2397 * entering the SCI_BASE_PORT_STATE_READY. This function sets the ready state 2398 * handlers for the struct scic_sds_port object, reports the port object as 2399 * not ready and starts the ready substate machine. none 2400 */ 2401static void scic_sds_port_ready_state_enter(void *object) 2402{ 2403 struct scic_sds_port *sci_port = object; 2404 struct scic_sds_controller *scic = sci_port->owning_controller; 2405 struct isci_host *ihost = scic_to_ihost(scic); 2406 struct isci_port *iport = sci_port_to_iport(sci_port); 2407 u32 prev_state; 2408 2409 /* Put the ready state handlers in place though they will not be there long */ 2410 scic_sds_port_set_base_state_handlers(sci_port, SCI_BASE_PORT_STATE_READY); 2411 2412 prev_state = sci_port->state_machine.previous_state_id; 2413 if (prev_state == SCI_BASE_PORT_STATE_RESETTING) 2414 isci_port_hard_reset_complete(iport, SCI_SUCCESS); 2415 else 2416 isci_port_not_ready(ihost, iport); 2417 2418 /* Post and suspend the dummy remote node context for this port. */ 2419 scic_sds_port_post_dummy_remote_node(sci_port); 2420 2421 /* Start the ready substate machine */ 2422 sci_base_state_machine_start(&sci_port->ready_substate_machine); 2423} 2424 2425static void scic_sds_port_ready_state_exit(void *object) 2426{ 2427 struct scic_sds_port *sci_port = object; 2428 2429 sci_base_state_machine_stop(&sci_port->ready_substate_machine); 2430 scic_sds_port_invalidate_dummy_remote_node(sci_port); 2431} 2432 2433/** 2434 * 2435 * @object: This is the object which is cast to a struct scic_sds_port object. 2436 * 2437 * This method will perform the actions required by the struct scic_sds_port on 2438 * entering the SCI_BASE_PORT_STATE_RESETTING. This function sets the resetting 2439 * state handlers for the struct scic_sds_port object. none 2440 */ 2441static void scic_sds_port_resetting_state_enter(void *object) 2442{ 2443 struct scic_sds_port *sci_port = object; 2444 2445 scic_sds_port_set_base_state_handlers( 2446 sci_port, SCI_BASE_PORT_STATE_RESETTING 2447 ); 2448} 2449 2450/** 2451 * 2452 * @object: This is the object which is cast to a struct scic_sds_port object. 2453 * 2454 * This function will perform the actions required by the 2455 * struct scic_sds_port on 2456 * exiting the SCI_BASE_STATE_RESETTING. This function does nothing. none 2457 */ 2458static inline void scic_sds_port_resetting_state_exit(void *object) 2459{ 2460 struct scic_sds_port *sci_port = object; 2461 2462 isci_timer_stop(sci_port->timer_handle); 2463} 2464 2465/** 2466 * 2467 * @object: This is the void object which is cast to a 2468 * struct scic_sds_port object. 2469 * 2470 * This method will perform the actions required by the struct scic_sds_port on 2471 * entering the SCI_BASE_PORT_STATE_STOPPING. This function sets the stopping 2472 * state handlers for the struct scic_sds_port object. none 2473 */ 2474static void scic_sds_port_stopping_state_enter(void *object) 2475{ 2476 struct scic_sds_port *sci_port = object; 2477 2478 scic_sds_port_set_base_state_handlers( 2479 sci_port, SCI_BASE_PORT_STATE_STOPPING 2480 ); 2481} 2482 2483/** 2484 * 2485 * @object: This is the object which is cast to a struct scic_sds_port object. 2486 * 2487 * This function will perform the actions required by the 2488 * struct scic_sds_port on 2489 * exiting the SCI_BASE_STATE_STOPPING. This function does nothing. none 2490 */ 2491static inline void 2492scic_sds_port_stopping_state_exit(void *object) 2493{ 2494 struct scic_sds_port *sci_port = object; 2495 2496 isci_timer_stop(sci_port->timer_handle); 2497 2498 scic_sds_port_destroy_dummy_resources(sci_port); 2499} 2500 2501/** 2502 * 2503 * @object: This is the object which is cast to a struct scic_sds_port object. 2504 * 2505 * This function will perform the actions required by the 2506 * struct scic_sds_port on 2507 * entering the SCI_BASE_PORT_STATE_STOPPING. This function sets the stopping 2508 * state handlers for the struct scic_sds_port object. none 2509 */ 2510static void scic_sds_port_failed_state_enter(void *object) 2511{ 2512 struct scic_sds_port *sci_port = object; 2513 struct isci_port *iport = sci_port_to_iport(sci_port); 2514 2515 scic_sds_port_set_base_state_handlers(sci_port, 2516 SCI_BASE_PORT_STATE_FAILED); 2517 2518 isci_port_hard_reset_complete(iport, SCI_FAILURE_TIMEOUT); 2519} 2520 2521/* --------------------------------------------------------------------------- */ 2522 2523static const struct sci_base_state scic_sds_port_state_table[] = { 2524 [SCI_BASE_PORT_STATE_STOPPED] = { 2525 .enter_state = scic_sds_port_stopped_state_enter, 2526 .exit_state = scic_sds_port_stopped_state_exit 2527 }, 2528 [SCI_BASE_PORT_STATE_STOPPING] = { 2529 .enter_state = scic_sds_port_stopping_state_enter, 2530 .exit_state = scic_sds_port_stopping_state_exit 2531 }, 2532 [SCI_BASE_PORT_STATE_READY] = { 2533 .enter_state = scic_sds_port_ready_state_enter, 2534 .exit_state = scic_sds_port_ready_state_exit 2535 }, 2536 [SCI_BASE_PORT_STATE_RESETTING] = { 2537 .enter_state = scic_sds_port_resetting_state_enter, 2538 .exit_state = scic_sds_port_resetting_state_exit 2539 }, 2540 [SCI_BASE_PORT_STATE_FAILED] = { 2541 .enter_state = scic_sds_port_failed_state_enter, 2542 } 2543}; 2544 2545void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 index, 2546 struct scic_sds_controller *scic) 2547{ 2548 sci_base_state_machine_construct(&sci_port->state_machine, 2549 sci_port, 2550 scic_sds_port_state_table, 2551 SCI_BASE_PORT_STATE_STOPPED); 2552 2553 sci_base_state_machine_start(&sci_port->state_machine); 2554 2555 sci_base_state_machine_construct(&sci_port->ready_substate_machine, 2556 sci_port, 2557 scic_sds_port_ready_substate_table, 2558 SCIC_SDS_PORT_READY_SUBSTATE_WAITING); 2559 2560 sci_port->logical_port_index = SCIC_SDS_DUMMY_PORT; 2561 sci_port->physical_port_index = index; 2562 sci_port->active_phy_mask = 0; 2563 2564 sci_port->owning_controller = scic; 2565 2566 sci_port->started_request_count = 0; 2567 sci_port->assigned_device_count = 0; 2568 2569 sci_port->reserved_rni = SCU_DUMMY_INDEX; 2570 sci_port->reserved_tci = SCU_DUMMY_INDEX; 2571 2572 sci_port->timer_handle = NULL; 2573 sci_port->port_task_scheduler_registers = NULL; 2574 2575 for (index = 0; index < SCI_MAX_PHYS; index++) 2576 sci_port->phy_table[index] = NULL; 2577} 2578 2579void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index) 2580{ 2581 INIT_LIST_HEAD(&iport->remote_dev_list); 2582 INIT_LIST_HEAD(&iport->domain_dev_list); 2583 spin_lock_init(&iport->state_lock); 2584 init_completion(&iport->start_complete); 2585 iport->isci_host = ihost; 2586 isci_port_change_state(iport, isci_freed); 2587} 2588 2589/** 2590 * isci_port_get_state() - This function gets the status of the port object. 2591 * @isci_port: This parameter points to the isci_port object 2592 * 2593 * status of the object as a isci_status enum. 2594 */ 2595enum isci_status isci_port_get_state( 2596 struct isci_port *isci_port) 2597{ 2598 return isci_port->status; 2599} 2600 2601static void isci_port_bc_change_received(struct isci_host *ihost, 2602 struct scic_sds_port *sci_port, 2603 struct scic_sds_phy *sci_phy) 2604{ 2605 struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); 2606 2607 dev_dbg(&ihost->pdev->dev, "%s: iphy = %p, sas_phy = %p\n", 2608 __func__, iphy, &iphy->sas_phy); 2609 2610 ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD); 2611 scic_port_enable_broadcast_change_notification(sci_port); 2612} 2613 2614void scic_sds_port_broadcast_change_received( 2615 struct scic_sds_port *sci_port, 2616 struct scic_sds_phy *sci_phy) 2617{ 2618 struct scic_sds_controller *scic = sci_port->owning_controller; 2619 struct isci_host *ihost = scic_to_ihost(scic); 2620 2621 /* notify the user. */ 2622 isci_port_bc_change_received(ihost, sci_port, sci_phy); 2623} 2624 |
|
309int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport, 310 struct isci_phy *iphy) 311{ 312 unsigned long flags; 313 enum sci_status status; 314 int ret = TMF_RESP_FUNC_COMPLETE; 315 316 dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n", --- 37 unchanged lines hidden (view full) --- 354 __func__, iport, iport->hard_reset_status, iphy); 355 356 isci_port_link_down(ihost, iphy, iport); 357 } 358 359 return ret; 360} 361 | 2625int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport, 2626 struct isci_phy *iphy) 2627{ 2628 unsigned long flags; 2629 enum sci_status status; 2630 int ret = TMF_RESP_FUNC_COMPLETE; 2631 2632 dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n", --- 37 unchanged lines hidden (view full) --- 2670 __func__, iport, iport->hard_reset_status, iphy); 2671 2672 isci_port_link_down(ihost, iphy, iport); 2673 } 2674 2675 return ret; 2676} 2677 |
362void isci_port_stop_complete(struct scic_sds_controller *scic, 363 struct scic_sds_port *sci_port, 364 enum sci_status completion_status) | 2678/** 2679 * isci_port_deformed() - This function is called by libsas when a port becomes 2680 * inactive. 2681 * @phy: This parameter specifies the libsas phy with the inactive port. 2682 * 2683 */ 2684void isci_port_deformed(struct asd_sas_phy *phy) |
365{ | 2685{ |
366 dev_dbg(&scic_to_ihost(scic)->pdev->dev, "Port stop complete\n"); | 2686 pr_debug("%s: sas_phy = %p\n", __func__, phy); |
367} | 2687} |
2688 2689/** 2690 * isci_port_formed() - This function is called by libsas when a port becomes 2691 * active. 2692 * @phy: This parameter specifies the libsas phy with the active port. 2693 * 2694 */ 2695void isci_port_formed(struct asd_sas_phy *phy) 2696{ 2697 pr_debug("%s: sas_phy = %p, sas_port = %p\n", __func__, phy, phy->port); 2698} |
|