diff options
author | Dave Jiang <dave.jiang@intel.com> | 2011-03-02 15:31:24 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 06:55:29 -0400 |
commit | 4d07f7f367f2c2d5547684893e61a7a796c1547f (patch) | |
tree | ffcd0f706f0f4729bb84fd75f906578b66148948 | |
parent | c658b109d3a9444293700471a278a741a1e5033d (diff) |
isci: Adding support for phy enable and disable
Adding support for PHY_FUNC_LINK_RESET and PHY_FUNC_DISABLE. This allow the
sysfs knob enable (both 0 and 1) and link_reset to work properly.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_phy.c | 32 | ||||
-rw-r--r-- | drivers/scsi/isci/phy.c | 59 |
2 files changed, 54 insertions, 37 deletions
diff --git a/drivers/scsi/isci/core/scic_sds_phy.c b/drivers/scsi/isci/core/scic_sds_phy.c index ba9e55756f26..6f00ff6aa6bf 100644 --- a/drivers/scsi/isci/core/scic_sds_phy.c +++ b/drivers/scsi/isci/core/scic_sds_phy.c | |||
@@ -537,27 +537,25 @@ void scic_sds_phy_get_attached_phy_protocols( | |||
537 | /** | 537 | /** |
538 | * This method will attempt to start the phy object. This request is only valid | 538 | * This method will attempt to start the phy object. This request is only valid |
539 | * when the phy is in the stopped state | 539 | * when the phy is in the stopped state |
540 | * @this_phy: | 540 | * @sci_phy: |
541 | * | 541 | * |
542 | * enum sci_status | 542 | * enum sci_status |
543 | */ | 543 | */ |
544 | enum sci_status scic_sds_phy_start( | 544 | enum sci_status scic_sds_phy_start(struct scic_sds_phy *sci_phy) |
545 | struct scic_sds_phy *this_phy) | ||
546 | { | 545 | { |
547 | return this_phy->state_handlers->parent.start_handler(&this_phy->parent); | 546 | return sci_phy->state_handlers->parent.start_handler(&sci_phy->parent); |
548 | } | 547 | } |
549 | 548 | ||
550 | /** | 549 | /** |
551 | * This method will attempt to stop the phy object. | 550 | * This method will attempt to stop the phy object. |
552 | * @this_phy: | 551 | * @sci_phy: |
553 | * | 552 | * |
554 | * enum sci_status SCI_SUCCESS if the phy is going to stop SCI_INVALID_STATE if the | 553 | * enum sci_status SCI_SUCCESS if the phy is going to stop SCI_INVALID_STATE |
555 | * phy is not in a valid state to stop | 554 | * if the phy is not in a valid state to stop |
556 | */ | 555 | */ |
557 | enum sci_status scic_sds_phy_stop( | 556 | enum sci_status scic_sds_phy_stop(struct scic_sds_phy *sci_phy) |
558 | struct scic_sds_phy *this_phy) | ||
559 | { | 557 | { |
560 | return this_phy->state_handlers->parent.stop_handler(&this_phy->parent); | 558 | return sci_phy->state_handlers->parent.stop_handler(&sci_phy->parent); |
561 | } | 559 | } |
562 | 560 | ||
563 | /** | 561 | /** |
@@ -2526,7 +2524,8 @@ static void scic_sds_phy_initial_state_enter( | |||
2526 | 2524 | ||
2527 | /** | 2525 | /** |
2528 | * | 2526 | * |
2529 | * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object. | 2527 | * @object: This is the struct sci_base_object which is cast to a |
2528 | * struct scic_sds_phy object. | ||
2530 | * | 2529 | * |
2531 | * This method will perform the actions required by the struct scic_sds_phy on | 2530 | * This method will perform the actions required by the struct scic_sds_phy on |
2532 | * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state | 2531 | * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state |
@@ -2539,7 +2538,10 @@ static void scic_sds_phy_stopped_state_enter(struct sci_base_object *object) | |||
2539 | 2538 | ||
2540 | sci_phy = (struct scic_sds_phy *)object; | 2539 | sci_phy = (struct scic_sds_phy *)object; |
2541 | 2540 | ||
2542 | /* / @todo We need to get to the controller to place this PE in a reset state */ | 2541 | /* |
2542 | * @todo We need to get to the controller to place this PE in a | ||
2543 | * reset state | ||
2544 | */ | ||
2543 | 2545 | ||
2544 | scic_sds_phy_set_base_state_handlers(sci_phy, SCI_BASE_PHY_STATE_STOPPED); | 2546 | scic_sds_phy_set_base_state_handlers(sci_phy, SCI_BASE_PHY_STATE_STOPPED); |
2545 | 2547 | ||
@@ -2551,6 +2553,12 @@ static void scic_sds_phy_stopped_state_enter(struct sci_base_object *object) | |||
2551 | } | 2553 | } |
2552 | 2554 | ||
2553 | scu_link_layer_stop_protocol_engine(sci_phy); | 2555 | scu_link_layer_stop_protocol_engine(sci_phy); |
2556 | |||
2557 | if (sci_phy->parent.state_machine.previous_state_id != | ||
2558 | SCI_BASE_PHY_STATE_INITIAL) | ||
2559 | scic_sds_controller_link_down(scic_sds_phy_get_controller(sci_phy), | ||
2560 | scic_sds_phy_get_port(sci_phy), | ||
2561 | sci_phy); | ||
2554 | } | 2562 | } |
2555 | 2563 | ||
2556 | /** | 2564 | /** |
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c index 1eefaaeb1141..decc0c05a3dd 100644 --- a/drivers/scsi/isci/phy.c +++ b/drivers/scsi/isci/phy.c | |||
@@ -58,6 +58,9 @@ | |||
58 | #include "scic_port.h" | 58 | #include "scic_port.h" |
59 | #include "scic_config_parameters.h" | 59 | #include "scic_config_parameters.h" |
60 | 60 | ||
61 | struct scic_sds_phy; | ||
62 | extern enum sci_status scic_sds_phy_start(struct scic_sds_phy *sci_phy); | ||
63 | extern enum sci_status scic_sds_phy_stop(struct scic_sds_phy *sci_phy); | ||
61 | 64 | ||
62 | /** | 65 | /** |
63 | * isci_phy_init() - This function is called by the probe function to | 66 | * isci_phy_init() - This function is called by the probe function to |
@@ -127,42 +130,48 @@ void isci_phy_init( | |||
127 | * | 130 | * |
128 | * status, zero indicates success. | 131 | * status, zero indicates success. |
129 | */ | 132 | */ |
130 | int isci_phy_control( | 133 | int isci_phy_control(struct asd_sas_phy *sas_phy, |
131 | struct asd_sas_phy *phy, | 134 | enum phy_func func, |
132 | enum phy_func func, | 135 | void *buf) |
133 | void *buf) | ||
134 | { | 136 | { |
135 | int ret = TMF_RESP_FUNC_COMPLETE; | 137 | int ret = 0; |
136 | struct isci_phy *isci_phy_ptr = (struct isci_phy *)phy->lldd_phy; | 138 | struct isci_phy *iphy = sas_phy->lldd_phy; |
137 | struct isci_port *isci_port_ptr = NULL; | 139 | struct isci_port *iport = iphy->isci_port; |
138 | 140 | struct isci_host *ihost = sas_phy->ha->lldd_ha; | |
139 | if (isci_phy_ptr != NULL) | 141 | unsigned long flags; |
140 | isci_port_ptr = isci_phy_ptr->isci_port; | ||
141 | |||
142 | if ((isci_phy_ptr == NULL) || (isci_port_ptr == NULL)) { | ||
143 | pr_err("%s: asd_sas_phy %p: lldd_phy %p or " | ||
144 | "isci_port %p == NULL!\n", | ||
145 | __func__, phy, isci_phy_ptr, isci_port_ptr); | ||
146 | return TMF_RESP_FUNC_FAILED; | ||
147 | } | ||
148 | 142 | ||
149 | pr_debug("%s: phy %p; func %d; buf %p; isci phy %p, port %p\n", | 143 | dev_dbg(&ihost->pdev->dev, |
150 | __func__, phy, func, buf, isci_phy_ptr, isci_port_ptr); | 144 | "%s: phy %p; func %d; buf %p; isci phy %p, port %p\n", |
145 | __func__, sas_phy, func, buf, iphy, iport); | ||
151 | 146 | ||
152 | switch (func) { | 147 | switch (func) { |
153 | case PHY_FUNC_HARD_RESET: | 148 | case PHY_FUNC_DISABLE: |
149 | spin_lock_irqsave(&ihost->scic_lock, flags); | ||
150 | scic_sds_phy_stop(iphy->sci_phy_handle); | ||
151 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | ||
152 | break; | ||
153 | |||
154 | case PHY_FUNC_LINK_RESET: | 154 | case PHY_FUNC_LINK_RESET: |
155 | spin_lock_irqsave(&ihost->scic_lock, flags); | ||
156 | scic_sds_phy_stop(iphy->sci_phy_handle); | ||
157 | scic_sds_phy_start(iphy->sci_phy_handle); | ||
158 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | ||
159 | break; | ||
160 | |||
161 | case PHY_FUNC_HARD_RESET: | ||
162 | if (!iport) | ||
163 | return -ENODEV; | ||
155 | 164 | ||
156 | /* Perform the port reset. */ | 165 | /* Perform the port reset. */ |
157 | ret = isci_port_perform_hard_reset(isci_port_ptr, isci_phy_ptr); | 166 | ret = isci_port_perform_hard_reset(iport, iphy); |
158 | 167 | ||
159 | break; | 168 | break; |
160 | 169 | ||
161 | case PHY_FUNC_DISABLE: | ||
162 | default: | 170 | default: |
163 | pr_debug("%s: phy %p; func %d NOT IMPLEMENTED!\n", | 171 | dev_dbg(&ihost->pdev->dev, |
164 | __func__, phy, func); | 172 | "%s: phy %p; func %d NOT IMPLEMENTED!\n", |
165 | ret = TMF_RESP_FUNC_FAILED; | 173 | __func__, sas_phy, func); |
174 | ret = -ENOSYS; | ||
166 | break; | 175 | break; |
167 | } | 176 | } |
168 | return ret; | 177 | return ret; |