aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/port_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/isci/port_config.c')
-rw-r--r--drivers/scsi/isci/port_config.c99
1 files changed, 47 insertions, 52 deletions
diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c
index 8444fd8219dd..bb62d2a25217 100644
--- a/drivers/scsi/isci/port_config.c
+++ b/drivers/scsi/isci/port_config.c
@@ -112,7 +112,7 @@ static s32 sci_sas_address_compare(
112 * port. port address if the port can be found to match the phy. 112 * port. port address if the port can be found to match the phy.
113 * NULL if there is no matching port for the phy. 113 * NULL if there is no matching port for the phy.
114 */ 114 */
115static struct scic_sds_port *scic_sds_port_configuration_agent_find_port( 115static struct isci_port *scic_sds_port_configuration_agent_find_port(
116 struct scic_sds_controller *scic, 116 struct scic_sds_controller *scic,
117 struct isci_phy *iphy) 117 struct isci_phy *iphy)
118{ 118{
@@ -132,14 +132,14 @@ static struct scic_sds_port *scic_sds_port_configuration_agent_find_port(
132 132
133 for (i = 0; i < scic->logical_port_entries; i++) { 133 for (i = 0; i < scic->logical_port_entries; i++) {
134 struct isci_host *ihost = scic_to_ihost(scic); 134 struct isci_host *ihost = scic_to_ihost(scic);
135 struct scic_sds_port *sci_port = &ihost->ports[i].sci; 135 struct isci_port *iport = &ihost->ports[i];
136 136
137 scic_sds_port_get_sas_address(sci_port, &port_sas_address); 137 scic_sds_port_get_sas_address(iport, &port_sas_address);
138 scic_sds_port_get_attached_sas_address(sci_port, &port_attached_device_address); 138 scic_sds_port_get_attached_sas_address(iport, &port_attached_device_address);
139 139
140 if (sci_sas_address_compare(port_sas_address, phy_sas_address) == 0 && 140 if (sci_sas_address_compare(port_sas_address, phy_sas_address) == 0 &&
141 sci_sas_address_compare(port_attached_device_address, phy_attached_device_address) == 0) 141 sci_sas_address_compare(port_attached_device_address, phy_attached_device_address) == 0)
142 return sci_port; 142 return iport;
143 } 143 }
144 144
145 return NULL; 145 return NULL;
@@ -315,7 +315,7 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration(
315 port_agent->phy_valid_port_range[phy_index].min_index = port_index; 315 port_agent->phy_valid_port_range[phy_index].min_index = port_index;
316 port_agent->phy_valid_port_range[phy_index].max_index = phy_index; 316 port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
317 317
318 scic_sds_port_add_phy(&ihost->ports[port_index].sci, 318 scic_sds_port_add_phy(&ihost->ports[port_index],
319 &ihost->phys[phy_index]); 319 &ihost->phys[phy_index]);
320 320
321 assigned_phy_mask |= (1 << phy_index); 321 assigned_phy_mask |= (1 << phy_index);
@@ -367,22 +367,20 @@ done:
367 367
368static void scic_sds_mpc_agent_link_up(struct scic_sds_controller *controller, 368static void scic_sds_mpc_agent_link_up(struct scic_sds_controller *controller,
369 struct scic_sds_port_configuration_agent *port_agent, 369 struct scic_sds_port_configuration_agent *port_agent,
370 struct scic_sds_port *port, 370 struct isci_port *iport,
371 struct isci_phy *iphy) 371 struct isci_phy *iphy)
372{ 372{
373 /* If the port has an invalid handle then the phy was not assigned to 373 /* If the port is NULL then the phy was not assigned to a port.
374 * a port. This is because the phy was not given the same SAS Address 374 * This is because the phy was not given the same SAS Address as
375 * as the other PHYs in the port. 375 * the other PHYs in the port.
376 */ 376 */
377 if (port != NULL) { 377 if (!iport)
378 port_agent->phy_ready_mask |= (1 << scic_sds_phy_get_index(iphy)); 378 return;
379
380 scic_sds_port_link_up(port, iphy);
381 379
382 if ((port->active_phy_mask & (1 << scic_sds_phy_get_index(iphy))) != 0) { 380 port_agent->phy_ready_mask |= (1 << scic_sds_phy_get_index(iphy));
383 port_agent->phy_configured_mask |= (1 << scic_sds_phy_get_index(iphy)); 381 scic_sds_port_link_up(iport, iphy);
384 } 382 if ((iport->active_phy_mask & (1 << scic_sds_phy_get_index(iphy))))
385 } 383 port_agent->phy_configured_mask |= (1 << scic_sds_phy_get_index(iphy));
386} 384}
387 385
388/** 386/**
@@ -405,10 +403,10 @@ static void scic_sds_mpc_agent_link_up(struct scic_sds_controller *controller,
405static void scic_sds_mpc_agent_link_down( 403static void scic_sds_mpc_agent_link_down(
406 struct scic_sds_controller *scic, 404 struct scic_sds_controller *scic,
407 struct scic_sds_port_configuration_agent *port_agent, 405 struct scic_sds_port_configuration_agent *port_agent,
408 struct scic_sds_port *sci_port, 406 struct isci_port *iport,
409 struct isci_phy *iphy) 407 struct isci_phy *iphy)
410{ 408{
411 if (sci_port != NULL) { 409 if (iport != NULL) {
412 /* 410 /*
413 * If we can form a new port from the remainder of the phys 411 * If we can form a new port from the remainder of the phys
414 * then we want to start the timer to allow the SCI User to 412 * then we want to start the timer to allow the SCI User to
@@ -436,7 +434,7 @@ static void scic_sds_mpc_agent_link_down(
436 SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT); 434 SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT);
437 } 435 }
438 436
439 scic_sds_port_link_down(sci_port, iphy); 437 scic_sds_port_link_down(iport, iphy);
440 } 438 }
441} 439}
442 440
@@ -496,14 +494,14 @@ static void scic_sds_apc_agent_configure_ports(struct scic_sds_controller *contr
496{ 494{
497 u8 port_index; 495 u8 port_index;
498 enum sci_status status; 496 enum sci_status status;
499 struct scic_sds_port *port; 497 struct isci_port *iport;
500 enum SCIC_SDS_APC_ACTIVITY apc_activity = SCIC_SDS_APC_SKIP_PHY; 498 enum SCIC_SDS_APC_ACTIVITY apc_activity = SCIC_SDS_APC_SKIP_PHY;
501 struct isci_host *ihost = scic_to_ihost(controller); 499 struct isci_host *ihost = scic_to_ihost(controller);
502 500
503 port = scic_sds_port_configuration_agent_find_port(controller, iphy); 501 iport = scic_sds_port_configuration_agent_find_port(controller, iphy);
504 502
505 if (port != NULL) { 503 if (iport) {
506 if (scic_sds_port_is_valid_phy_assignment(port, iphy->phy_index)) 504 if (scic_sds_port_is_valid_phy_assignment(iport, iphy->phy_index))
507 apc_activity = SCIC_SDS_APC_ADD_PHY; 505 apc_activity = SCIC_SDS_APC_ADD_PHY;
508 else 506 else
509 apc_activity = SCIC_SDS_APC_SKIP_PHY; 507 apc_activity = SCIC_SDS_APC_SKIP_PHY;
@@ -514,21 +512,19 @@ static void scic_sds_apc_agent_configure_ports(struct scic_sds_controller *contr
514 * the timer and wait to see if a wider port can be made. 512 * the timer and wait to see if a wider port can be made.
515 * 513 *
516 * Note the break when we reach the condition of the port id == phy id */ 514 * Note the break when we reach the condition of the port id == phy id */
517 for ( 515 for (port_index = port_agent->phy_valid_port_range[iphy->phy_index].min_index;
518 port_index = port_agent->phy_valid_port_range[iphy->phy_index].min_index; 516 port_index <= port_agent->phy_valid_port_range[iphy->phy_index].max_index;
519 port_index <= port_agent->phy_valid_port_range[iphy->phy_index].max_index; 517 port_index++) {
520 port_index++
521 ) {
522 518
523 port = &ihost->ports[port_index].sci; 519 iport = &ihost->ports[port_index];
524 520
525 /* First we must make sure that this PHY can be added to this Port. */ 521 /* First we must make sure that this PHY can be added to this Port. */
526 if (scic_sds_port_is_valid_phy_assignment(port, iphy->phy_index)) { 522 if (scic_sds_port_is_valid_phy_assignment(iport, iphy->phy_index)) {
527 /* 523 /*
528 * Port contains a PHY with a greater PHY ID than the current 524 * Port contains a PHY with a greater PHY ID than the current
529 * PHY that has gone link up. This phy can not be part of any 525 * PHY that has gone link up. This phy can not be part of any
530 * port so skip it and move on. */ 526 * port so skip it and move on. */
531 if (port->active_phy_mask > (1 << iphy->phy_index)) { 527 if (iport->active_phy_mask > (1 << iphy->phy_index)) {
532 apc_activity = SCIC_SDS_APC_SKIP_PHY; 528 apc_activity = SCIC_SDS_APC_SKIP_PHY;
533 break; 529 break;
534 } 530 }
@@ -537,7 +533,7 @@ static void scic_sds_apc_agent_configure_ports(struct scic_sds_controller *contr
537 * We have reached the end of our Port list and have not found 533 * We have reached the end of our Port list and have not found
538 * any reason why we should not either add the PHY to the port 534 * any reason why we should not either add the PHY to the port
539 * or wait for more phys to become active. */ 535 * or wait for more phys to become active. */
540 if (port->physical_port_index == iphy->phy_index) { 536 if (iport->physical_port_index == iphy->phy_index) {
541 /* 537 /*
542 * The Port either has no active PHYs. 538 * The Port either has no active PHYs.
543 * Consider that if the port had any active PHYs we would have 539 * Consider that if the port had any active PHYs we would have
@@ -554,10 +550,10 @@ static void scic_sds_apc_agent_configure_ports(struct scic_sds_controller *contr
554 * The current Port has no active PHYs and this PHY could be part 550 * The current Port has no active PHYs and this PHY could be part
555 * of this Port. Since we dont know as yet setup to start the 551 * of this Port. Since we dont know as yet setup to start the
556 * timer and see if there is a better configuration. */ 552 * timer and see if there is a better configuration. */
557 if (port->active_phy_mask == 0) { 553 if (iport->active_phy_mask == 0) {
558 apc_activity = SCIC_SDS_APC_START_TIMER; 554 apc_activity = SCIC_SDS_APC_START_TIMER;
559 } 555 }
560 } else if (port->active_phy_mask != 0) { 556 } else if (iport->active_phy_mask != 0) {
561 /* 557 /*
562 * The Port has an active phy and the current Phy can not 558 * The Port has an active phy and the current Phy can not
563 * participate in this port so skip the PHY and see if 559 * participate in this port so skip the PHY and see if
@@ -583,7 +579,7 @@ static void scic_sds_apc_agent_configure_ports(struct scic_sds_controller *contr
583 579
584 switch (apc_activity) { 580 switch (apc_activity) {
585 case SCIC_SDS_APC_ADD_PHY: 581 case SCIC_SDS_APC_ADD_PHY:
586 status = scic_sds_port_add_phy(port, iphy); 582 status = scic_sds_port_add_phy(iport, iphy);
587 583
588 if (status == SCI_SUCCESS) { 584 if (status == SCI_SUCCESS) {
589 port_agent->phy_configured_mask |= (1 << iphy->phy_index); 585 port_agent->phy_configured_mask |= (1 << iphy->phy_index);
@@ -625,18 +621,18 @@ static void scic_sds_apc_agent_configure_ports(struct scic_sds_controller *contr
625 */ 621 */
626static void scic_sds_apc_agent_link_up(struct scic_sds_controller *scic, 622static void scic_sds_apc_agent_link_up(struct scic_sds_controller *scic,
627 struct scic_sds_port_configuration_agent *port_agent, 623 struct scic_sds_port_configuration_agent *port_agent,
628 struct scic_sds_port *sci_port, 624 struct isci_port *iport,
629 struct isci_phy *iphy) 625 struct isci_phy *iphy)
630{ 626{
631 u8 phy_index = iphy->phy_index; 627 u8 phy_index = iphy->phy_index;
632 628
633 if (!sci_port) { 629 if (!iport) {
634 /* the phy is not the part of this port */ 630 /* the phy is not the part of this port */
635 port_agent->phy_ready_mask |= 1 << phy_index; 631 port_agent->phy_ready_mask |= 1 << phy_index;
636 scic_sds_apc_agent_configure_ports(scic, port_agent, iphy, true); 632 scic_sds_apc_agent_configure_ports(scic, port_agent, iphy, true);
637 } else { 633 } else {
638 /* the phy is already the part of the port */ 634 /* the phy is already the part of the port */
639 u32 port_state = sci_port->sm.current_state_id; 635 u32 port_state = iport->sm.current_state_id;
640 636
641 /* if the PORT'S state is resetting then the link up is from 637 /* if the PORT'S state is resetting then the link up is from
642 * port hard reset in this case, we need to tell the port 638 * port hard reset in this case, we need to tell the port
@@ -644,7 +640,7 @@ static void scic_sds_apc_agent_link_up(struct scic_sds_controller *scic,
644 */ 640 */
645 BUG_ON(port_state != SCI_PORT_RESETTING); 641 BUG_ON(port_state != SCI_PORT_RESETTING);
646 port_agent->phy_ready_mask |= 1 << phy_index; 642 port_agent->phy_ready_mask |= 1 << phy_index;
647 scic_sds_port_link_up(sci_port, iphy); 643 scic_sds_port_link_up(iport, iphy);
648 } 644 }
649} 645}
650 646
@@ -652,9 +648,9 @@ static void scic_sds_apc_agent_link_up(struct scic_sds_controller *scic,
652 * 648 *
653 * @controller: This is the controller object that receives the link down 649 * @controller: This is the controller object that receives the link down
654 * notification. 650 * notification.
655 * @port: This is the port object associated with the phy. If the is no 651 * @iport: This is the port object associated with the phy. If the is no
656 * associated port this is an NULL. 652 * associated port this is an NULL.
657 * @phy: This is the phy object which has gone link down. 653 * @iphy: This is the phy object which has gone link down.
658 * 654 *
659 * This method handles the automatic port configuration link down 655 * This method handles the automatic port configuration link down
660 * notifications. not associated with a port there is no action taken. Is it 656 * notifications. not associated with a port there is no action taken. Is it
@@ -664,21 +660,20 @@ static void scic_sds_apc_agent_link_up(struct scic_sds_controller *scic,
664static void scic_sds_apc_agent_link_down( 660static void scic_sds_apc_agent_link_down(
665 struct scic_sds_controller *controller, 661 struct scic_sds_controller *controller,
666 struct scic_sds_port_configuration_agent *port_agent, 662 struct scic_sds_port_configuration_agent *port_agent,
667 struct scic_sds_port *port, 663 struct isci_port *iport,
668 struct isci_phy *iphy) 664 struct isci_phy *iphy)
669{ 665{
670 port_agent->phy_ready_mask &= ~(1 << scic_sds_phy_get_index(iphy)); 666 port_agent->phy_ready_mask &= ~(1 << scic_sds_phy_get_index(iphy));
671 667
672 if (port != NULL) { 668 if (!iport)
673 if (port_agent->phy_configured_mask & (1 << iphy->phy_index)) { 669 return;
674 enum sci_status status; 670 if (port_agent->phy_configured_mask & (1 << iphy->phy_index)) {
671 enum sci_status status;
675 672
676 status = scic_sds_port_remove_phy(port, iphy); 673 status = scic_sds_port_remove_phy(iport, iphy);
677 674
678 if (status == SCI_SUCCESS) { 675 if (status == SCI_SUCCESS)
679 port_agent->phy_configured_mask &= ~(1 << iphy->phy_index); 676 port_agent->phy_configured_mask &= ~(1 << iphy->phy_index);
680 }
681 }
682 } 677 }
683} 678}
684 679