aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/port.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-18 15:35:17 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-18 15:35:17 -0500
commitd71f5be276bf79eda14c40f3cafcf827326f10cb (patch)
tree581dadb90b06b950882a8eb75deee23d3370a4ab /drivers/scsi/isci/port.c
parent92b5abbb44e05cdbc4483219f30a435dd871a8ea (diff)
parent76ffe8a3f766358a0ade543153625b3e4e66159d (diff)
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
SCSI updates on 20120118 * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (49 commits) [SCSI] libfc: remove redundant timer init for fcp [SCSI] fcoe: Move fcoe_debug_logging from fcoe.h to fcoe.c [SCSI] libfc: Declare local functions static [SCSI] fcoe: fix regression on offload em matching function for initiator/target [SCSI] qla4xxx: Update driver version to 5.02.00-k12 [SCSI] qla4xxx: Cleanup modinfo display [SCSI] qla4xxx: Update license [SCSI] qla4xxx: Clear the RISC interrupt bit during FW init [SCSI] qla4xxx: Added error logging for firmware abort [SCSI] qla4xxx: Disable generating pause frames in case of FW hung [SCSI] qla4xxx: Temperature monitoring for ISP82XX core. [SCSI] megaraid: fix sparse warnings [SCSI] sg: convert to kstrtoul_from_user() [SCSI] don't change sdev starvation list order without request dispatched [SCSI] isci: fix, prevent port from getting stuck in the 'configuring' state [SCSI] isci: fix start OOB [SCSI] isci: fix io failures while wide port links are coming up [SCSI] isci: allow more time for wide port targets [SCSI] isci: enable wide port targets [SCSI] isci: Fix IO fails when pull cable from phy in x4 wideport in MPC mode. ...
Diffstat (limited to 'drivers/scsi/isci/port.c')
-rw-r--r--drivers/scsi/isci/port.c104
1 files changed, 58 insertions, 46 deletions
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index ac7f27749f97..7c6ac58a5c4c 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -114,7 +114,7 @@ static u32 sci_port_get_phys(struct isci_port *iport)
114 * value is returned if the specified port is not valid. When this value is 114 * value is returned if the specified port is not valid. When this value is
115 * returned, no data is copied to the properties output parameter. 115 * returned, no data is copied to the properties output parameter.
116 */ 116 */
117static enum sci_status sci_port_get_properties(struct isci_port *iport, 117enum sci_status sci_port_get_properties(struct isci_port *iport,
118 struct sci_port_properties *prop) 118 struct sci_port_properties *prop)
119{ 119{
120 if (!iport || iport->logical_port_index == SCIC_SDS_DUMMY_PORT) 120 if (!iport || iport->logical_port_index == SCIC_SDS_DUMMY_PORT)
@@ -647,19 +647,26 @@ void sci_port_setup_transports(struct isci_port *iport, u32 device_id)
647 } 647 }
648} 648}
649 649
650static void sci_port_activate_phy(struct isci_port *iport, struct isci_phy *iphy, 650static void sci_port_resume_phy(struct isci_port *iport, struct isci_phy *iphy)
651 bool do_notify_user) 651{
652 sci_phy_resume(iphy);
653 iport->enabled_phy_mask |= 1 << iphy->phy_index;
654}
655
656static void sci_port_activate_phy(struct isci_port *iport,
657 struct isci_phy *iphy,
658 u8 flags)
652{ 659{
653 struct isci_host *ihost = iport->owning_controller; 660 struct isci_host *ihost = iport->owning_controller;
654 661
655 if (iphy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA) 662 if (iphy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA && (flags & PF_RESUME))
656 sci_phy_resume(iphy); 663 sci_phy_resume(iphy);
657 664
658 iport->active_phy_mask |= 1 << iphy->phy_index; 665 iport->active_phy_mask |= 1 << iphy->phy_index;
659 666
660 sci_controller_clear_invalid_phy(ihost, iphy); 667 sci_controller_clear_invalid_phy(ihost, iphy);
661 668
662 if (do_notify_user == true) 669 if (flags & PF_NOTIFY)
663 isci_port_link_up(ihost, iport, iphy); 670 isci_port_link_up(ihost, iport, iphy);
664} 671}
665 672
@@ -669,14 +676,19 @@ void sci_port_deactivate_phy(struct isci_port *iport, struct isci_phy *iphy,
669 struct isci_host *ihost = iport->owning_controller; 676 struct isci_host *ihost = iport->owning_controller;
670 677
671 iport->active_phy_mask &= ~(1 << iphy->phy_index); 678 iport->active_phy_mask &= ~(1 << iphy->phy_index);
679 iport->enabled_phy_mask &= ~(1 << iphy->phy_index);
672 if (!iport->active_phy_mask) 680 if (!iport->active_phy_mask)
673 iport->last_active_phy = iphy->phy_index; 681 iport->last_active_phy = iphy->phy_index;
674 682
675 iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN; 683 iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
676 684
677 /* Re-assign the phy back to the LP as if it were a narrow port */ 685 /* Re-assign the phy back to the LP as if it were a narrow port for APC
678 writel(iphy->phy_index, 686 * mode. For MPC mode, the phy will remain in the port.
679 &iport->port_pe_configuration_register[iphy->phy_index]); 687 */
688 if (iport->owning_controller->oem_parameters.controller.mode_type ==
689 SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE)
690 writel(iphy->phy_index,
691 &iport->port_pe_configuration_register[iphy->phy_index]);
680 692
681 if (do_notify_user == true) 693 if (do_notify_user == true)
682 isci_port_link_down(ihost, iphy, iport); 694 isci_port_link_down(ihost, iphy, iport);
@@ -701,18 +713,16 @@ static void sci_port_invalid_link_up(struct isci_port *iport, struct isci_phy *i
701 * sci_port_general_link_up_handler - phy can be assigned to port? 713 * sci_port_general_link_up_handler - phy can be assigned to port?
702 * @sci_port: sci_port object for which has a phy that has gone link up. 714 * @sci_port: sci_port object for which has a phy that has gone link up.
703 * @sci_phy: This is the struct isci_phy object that has gone link up. 715 * @sci_phy: This is the struct isci_phy object that has gone link up.
704 * @do_notify_user: This parameter specifies whether to inform the user (via 716 * @flags: PF_RESUME, PF_NOTIFY to sci_port_activate_phy
705 * sci_port_link_up()) as to the fact that a new phy as become ready.
706 * 717 *
707 * Determine if this phy can be assigned to this 718 * Determine if this phy can be assigned to this port . If the phy is
708 * port . If the phy is not a valid PHY for 719 * not a valid PHY for this port then the function will notify the user.
709 * this port then the function will notify the user. A PHY can only be 720 * A PHY can only be part of a port if it's attached SAS ADDRESS is the
710 * part of a port if it's attached SAS ADDRESS is the same as all other PHYs in 721 * same as all other PHYs in the same port.
711 * the same port. none
712 */ 722 */
713static void sci_port_general_link_up_handler(struct isci_port *iport, 723static void sci_port_general_link_up_handler(struct isci_port *iport,
714 struct isci_phy *iphy, 724 struct isci_phy *iphy,
715 bool do_notify_user) 725 u8 flags)
716{ 726{
717 struct sci_sas_address port_sas_address; 727 struct sci_sas_address port_sas_address;
718 struct sci_sas_address phy_sas_address; 728 struct sci_sas_address phy_sas_address;
@@ -730,7 +740,7 @@ static void sci_port_general_link_up_handler(struct isci_port *iport,
730 iport->active_phy_mask == 0) { 740 iport->active_phy_mask == 0) {
731 struct sci_base_state_machine *sm = &iport->sm; 741 struct sci_base_state_machine *sm = &iport->sm;
732 742
733 sci_port_activate_phy(iport, iphy, do_notify_user); 743 sci_port_activate_phy(iport, iphy, flags);
734 if (sm->current_state_id == SCI_PORT_RESETTING) 744 if (sm->current_state_id == SCI_PORT_RESETTING)
735 port_state_machine_change(iport, SCI_PORT_READY); 745 port_state_machine_change(iport, SCI_PORT_READY);
736 } else 746 } else
@@ -781,11 +791,16 @@ bool sci_port_link_detected(
781 struct isci_phy *iphy) 791 struct isci_phy *iphy)
782{ 792{
783 if ((iport->logical_port_index != SCIC_SDS_DUMMY_PORT) && 793 if ((iport->logical_port_index != SCIC_SDS_DUMMY_PORT) &&
784 (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) && 794 (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA)) {
785 sci_port_is_wide(iport)) { 795 if (sci_port_is_wide(iport)) {
786 sci_port_invalid_link_up(iport, iphy); 796 sci_port_invalid_link_up(iport, iphy);
787 797 return false;
788 return false; 798 } else {
799 struct isci_host *ihost = iport->owning_controller;
800 struct isci_port *dst_port = &(ihost->ports[iphy->phy_index]);
801 writel(iphy->phy_index,
802 &dst_port->port_pe_configuration_register[iphy->phy_index]);
803 }
789 } 804 }
790 805
791 return true; 806 return true;
@@ -975,6 +990,13 @@ static void sci_port_ready_substate_waiting_enter(struct sci_base_state_machine
975 } 990 }
976} 991}
977 992
993static void scic_sds_port_ready_substate_waiting_exit(
994 struct sci_base_state_machine *sm)
995{
996 struct isci_port *iport = container_of(sm, typeof(*iport), sm);
997 sci_port_resume_port_task_scheduler(iport);
998}
999
978static void sci_port_ready_substate_operational_enter(struct sci_base_state_machine *sm) 1000static void sci_port_ready_substate_operational_enter(struct sci_base_state_machine *sm)
979{ 1001{
980 u32 index; 1002 u32 index;
@@ -988,13 +1010,13 @@ static void sci_port_ready_substate_operational_enter(struct sci_base_state_mach
988 writel(iport->physical_port_index, 1010 writel(iport->physical_port_index,
989 &iport->port_pe_configuration_register[ 1011 &iport->port_pe_configuration_register[
990 iport->phy_table[index]->phy_index]); 1012 iport->phy_table[index]->phy_index]);
1013 if (((iport->active_phy_mask^iport->enabled_phy_mask) & (1 << index)) != 0)
1014 sci_port_resume_phy(iport, iport->phy_table[index]);
991 } 1015 }
992 } 1016 }
993 1017
994 sci_port_update_viit_entry(iport); 1018 sci_port_update_viit_entry(iport);
995 1019
996 sci_port_resume_port_task_scheduler(iport);
997
998 /* 1020 /*
999 * Post the dummy task for the port so the hardware can schedule 1021 * Post the dummy task for the port so the hardware can schedule
1000 * io correctly 1022 * io correctly
@@ -1061,20 +1083,9 @@ static void sci_port_ready_substate_configuring_enter(struct sci_base_state_mach
1061 if (iport->active_phy_mask == 0) { 1083 if (iport->active_phy_mask == 0) {
1062 isci_port_not_ready(ihost, iport); 1084 isci_port_not_ready(ihost, iport);
1063 1085
1064 port_state_machine_change(iport, 1086 port_state_machine_change(iport, SCI_PORT_SUB_WAITING);
1065 SCI_PORT_SUB_WAITING); 1087 } else
1066 } else if (iport->started_request_count == 0) 1088 port_state_machine_change(iport, SCI_PORT_SUB_OPERATIONAL);
1067 port_state_machine_change(iport,
1068 SCI_PORT_SUB_OPERATIONAL);
1069}
1070
1071static void sci_port_ready_substate_configuring_exit(struct sci_base_state_machine *sm)
1072{
1073 struct isci_port *iport = container_of(sm, typeof(*iport), sm);
1074
1075 sci_port_suspend_port_task_scheduler(iport);
1076 if (iport->ready_exit)
1077 sci_port_invalidate_dummy_remote_node(iport);
1078} 1089}
1079 1090
1080enum sci_status sci_port_start(struct isci_port *iport) 1091enum sci_status sci_port_start(struct isci_port *iport)
@@ -1252,7 +1263,7 @@ enum sci_status sci_port_add_phy(struct isci_port *iport,
1252 if (status != SCI_SUCCESS) 1263 if (status != SCI_SUCCESS)
1253 return status; 1264 return status;
1254 1265
1255 sci_port_general_link_up_handler(iport, iphy, true); 1266 sci_port_general_link_up_handler(iport, iphy, PF_NOTIFY|PF_RESUME);
1256 iport->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING; 1267 iport->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
1257 port_state_machine_change(iport, SCI_PORT_SUB_CONFIGURING); 1268 port_state_machine_change(iport, SCI_PORT_SUB_CONFIGURING);
1258 1269
@@ -1262,7 +1273,7 @@ enum sci_status sci_port_add_phy(struct isci_port *iport,
1262 1273
1263 if (status != SCI_SUCCESS) 1274 if (status != SCI_SUCCESS)
1264 return status; 1275 return status;
1265 sci_port_general_link_up_handler(iport, iphy, true); 1276 sci_port_general_link_up_handler(iport, iphy, PF_NOTIFY);
1266 1277
1267 /* Re-enter the configuring state since this may be the last phy in 1278 /* Re-enter the configuring state since this may be the last phy in
1268 * the port. 1279 * the port.
@@ -1338,13 +1349,13 @@ enum sci_status sci_port_link_up(struct isci_port *iport,
1338 /* Since this is the first phy going link up for the port we 1349 /* Since this is the first phy going link up for the port we
1339 * can just enable it and continue 1350 * can just enable it and continue
1340 */ 1351 */
1341 sci_port_activate_phy(iport, iphy, true); 1352 sci_port_activate_phy(iport, iphy, PF_NOTIFY|PF_RESUME);
1342 1353
1343 port_state_machine_change(iport, 1354 port_state_machine_change(iport,
1344 SCI_PORT_SUB_OPERATIONAL); 1355 SCI_PORT_SUB_OPERATIONAL);
1345 return SCI_SUCCESS; 1356 return SCI_SUCCESS;
1346 case SCI_PORT_SUB_OPERATIONAL: 1357 case SCI_PORT_SUB_OPERATIONAL:
1347 sci_port_general_link_up_handler(iport, iphy, true); 1358 sci_port_general_link_up_handler(iport, iphy, PF_NOTIFY|PF_RESUME);
1348 return SCI_SUCCESS; 1359 return SCI_SUCCESS;
1349 case SCI_PORT_RESETTING: 1360 case SCI_PORT_RESETTING:
1350 /* TODO We should make sure that the phy that has gone 1361 /* TODO We should make sure that the phy that has gone
@@ -1361,7 +1372,7 @@ enum sci_status sci_port_link_up(struct isci_port *iport,
1361 /* In the resetting state we don't notify the user regarding 1372 /* In the resetting state we don't notify the user regarding
1362 * link up and link down notifications. 1373 * link up and link down notifications.
1363 */ 1374 */
1364 sci_port_general_link_up_handler(iport, iphy, false); 1375 sci_port_general_link_up_handler(iport, iphy, PF_RESUME);
1365 return SCI_SUCCESS; 1376 return SCI_SUCCESS;
1366 default: 1377 default:
1367 dev_warn(sciport_to_dev(iport), 1378 dev_warn(sciport_to_dev(iport),
@@ -1584,14 +1595,14 @@ static const struct sci_base_state sci_port_state_table[] = {
1584 }, 1595 },
1585 [SCI_PORT_SUB_WAITING] = { 1596 [SCI_PORT_SUB_WAITING] = {
1586 .enter_state = sci_port_ready_substate_waiting_enter, 1597 .enter_state = sci_port_ready_substate_waiting_enter,
1598 .exit_state = scic_sds_port_ready_substate_waiting_exit,
1587 }, 1599 },
1588 [SCI_PORT_SUB_OPERATIONAL] = { 1600 [SCI_PORT_SUB_OPERATIONAL] = {
1589 .enter_state = sci_port_ready_substate_operational_enter, 1601 .enter_state = sci_port_ready_substate_operational_enter,
1590 .exit_state = sci_port_ready_substate_operational_exit 1602 .exit_state = sci_port_ready_substate_operational_exit
1591 }, 1603 },
1592 [SCI_PORT_SUB_CONFIGURING] = { 1604 [SCI_PORT_SUB_CONFIGURING] = {
1593 .enter_state = sci_port_ready_substate_configuring_enter, 1605 .enter_state = sci_port_ready_substate_configuring_enter
1594 .exit_state = sci_port_ready_substate_configuring_exit
1595 }, 1606 },
1596 [SCI_PORT_RESETTING] = { 1607 [SCI_PORT_RESETTING] = {
1597 .exit_state = sci_port_resetting_state_exit 1608 .exit_state = sci_port_resetting_state_exit
@@ -1609,6 +1620,7 @@ void sci_port_construct(struct isci_port *iport, u8 index,
1609 iport->logical_port_index = SCIC_SDS_DUMMY_PORT; 1620 iport->logical_port_index = SCIC_SDS_DUMMY_PORT;
1610 iport->physical_port_index = index; 1621 iport->physical_port_index = index;
1611 iport->active_phy_mask = 0; 1622 iport->active_phy_mask = 0;
1623 iport->enabled_phy_mask = 0;
1612 iport->last_active_phy = 0; 1624 iport->last_active_phy = 0;
1613 iport->ready_exit = false; 1625 iport->ready_exit = false;
1614 1626