diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-13 18:51:24 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 16:37:48 -0400 |
commit | dd5aaf4536c5111784a18d935b9b5adeac9f914c (patch) | |
tree | 14902190b847f78c638880b63392b909fbcc3234 /drivers/scsi/bfa/bfa_fcs_lport.c | |
parent | 111892082ed7a3214bc7a7ec6b8b20e8f847501a (diff) |
[SCSI] bfa: Changes to support vport disable and enable operations.
Made changes to FCS lport, vport state machines to support vport
enable / disable operations.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_fcs_lport.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs_lport.c | 147 |
1 files changed, 146 insertions, 1 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 1d6be8c1447..a0c6f960b99 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c | |||
@@ -74,6 +74,7 @@ enum bfa_fcs_lport_event { | |||
74 | BFA_FCS_PORT_SM_OFFLINE = 3, | 74 | BFA_FCS_PORT_SM_OFFLINE = 3, |
75 | BFA_FCS_PORT_SM_DELETE = 4, | 75 | BFA_FCS_PORT_SM_DELETE = 4, |
76 | BFA_FCS_PORT_SM_DELRPORT = 5, | 76 | BFA_FCS_PORT_SM_DELRPORT = 5, |
77 | BFA_FCS_PORT_SM_STOP = 6, | ||
77 | }; | 78 | }; |
78 | 79 | ||
79 | static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port, | 80 | static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port, |
@@ -86,6 +87,8 @@ static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port, | |||
86 | enum bfa_fcs_lport_event event); | 87 | enum bfa_fcs_lport_event event); |
87 | static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port, | 88 | static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port, |
88 | enum bfa_fcs_lport_event event); | 89 | enum bfa_fcs_lport_event event); |
90 | static void bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, | ||
91 | enum bfa_fcs_lport_event event); | ||
89 | 92 | ||
90 | static void | 93 | static void |
91 | bfa_fcs_lport_sm_uninit( | 94 | bfa_fcs_lport_sm_uninit( |
@@ -123,6 +126,12 @@ bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, | |||
123 | bfa_fcs_lport_deleted(port); | 126 | bfa_fcs_lport_deleted(port); |
124 | break; | 127 | break; |
125 | 128 | ||
129 | case BFA_FCS_PORT_SM_STOP: | ||
130 | /* If vport - send completion call back */ | ||
131 | if (port->vport) | ||
132 | bfa_fcs_vport_stop_comp(port->vport); | ||
133 | break; | ||
134 | |||
126 | case BFA_FCS_PORT_SM_OFFLINE: | 135 | case BFA_FCS_PORT_SM_OFFLINE: |
127 | break; | 136 | break; |
128 | 137 | ||
@@ -148,6 +157,23 @@ bfa_fcs_lport_sm_online( | |||
148 | bfa_fcs_lport_offline_actions(port); | 157 | bfa_fcs_lport_offline_actions(port); |
149 | break; | 158 | break; |
150 | 159 | ||
160 | case BFA_FCS_PORT_SM_STOP: | ||
161 | __port_action[port->fabric->fab_type].offline(port); | ||
162 | |||
163 | if (port->num_rports == 0) { | ||
164 | bfa_sm_set_state(port, bfa_fcs_lport_sm_init); | ||
165 | /* If vport - send completion call back */ | ||
166 | if (port->vport) | ||
167 | bfa_fcs_vport_stop_comp(port->vport); | ||
168 | } else { | ||
169 | bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); | ||
170 | list_for_each_safe(qe, qen, &port->rport_q) { | ||
171 | rport = (struct bfa_fcs_rport_s *) qe; | ||
172 | bfa_sm_send_event(rport, RPSM_EVENT_DELETE); | ||
173 | } | ||
174 | } | ||
175 | break; | ||
176 | |||
151 | case BFA_FCS_PORT_SM_DELETE: | 177 | case BFA_FCS_PORT_SM_DELETE: |
152 | 178 | ||
153 | __port_action[port->fabric->fab_type].offline(port); | 179 | __port_action[port->fabric->fab_type].offline(port); |
@@ -189,6 +215,21 @@ bfa_fcs_lport_sm_offline( | |||
189 | bfa_fcs_lport_online_actions(port); | 215 | bfa_fcs_lport_online_actions(port); |
190 | break; | 216 | break; |
191 | 217 | ||
218 | case BFA_FCS_PORT_SM_STOP: | ||
219 | if (port->num_rports == 0) { | ||
220 | bfa_sm_set_state(port, bfa_fcs_lport_sm_init); | ||
221 | /* If vport - send completion call back */ | ||
222 | if (port->vport) | ||
223 | bfa_fcs_vport_stop_comp(port->vport); | ||
224 | } else { | ||
225 | bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); | ||
226 | list_for_each_safe(qe, qen, &port->rport_q) { | ||
227 | rport = (struct bfa_fcs_rport_s *) qe; | ||
228 | bfa_sm_send_event(rport, RPSM_EVENT_DELETE); | ||
229 | } | ||
230 | } | ||
231 | break; | ||
232 | |||
192 | case BFA_FCS_PORT_SM_DELETE: | 233 | case BFA_FCS_PORT_SM_DELETE: |
193 | if (port->num_rports == 0) { | 234 | if (port->num_rports == 0) { |
194 | bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); | 235 | bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); |
@@ -212,6 +253,28 @@ bfa_fcs_lport_sm_offline( | |||
212 | } | 253 | } |
213 | 254 | ||
214 | static void | 255 | static void |
256 | bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, | ||
257 | enum bfa_fcs_lport_event event) | ||
258 | { | ||
259 | bfa_trc(port->fcs, port->port_cfg.pwwn); | ||
260 | bfa_trc(port->fcs, event); | ||
261 | |||
262 | switch (event) { | ||
263 | case BFA_FCS_PORT_SM_DELRPORT: | ||
264 | if (port->num_rports == 0) { | ||
265 | bfa_sm_set_state(port, bfa_fcs_lport_sm_init); | ||
266 | /* If vport - send completion call back */ | ||
267 | if (port->vport) | ||
268 | bfa_fcs_vport_stop_comp(port->vport); | ||
269 | } | ||
270 | break; | ||
271 | |||
272 | default: | ||
273 | bfa_sm_fault(port->fcs, event); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | static void | ||
215 | bfa_fcs_lport_sm_deleting( | 278 | bfa_fcs_lport_sm_deleting( |
216 | struct bfa_fcs_lport_s *port, | 279 | struct bfa_fcs_lport_s *port, |
217 | enum bfa_fcs_lport_event event) | 280 | enum bfa_fcs_lport_event event) |
@@ -1672,7 +1735,7 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) | |||
1672 | memcpy(attr->value, fcs_hba_attr->driver_version, templen); | 1735 | memcpy(attr->value, fcs_hba_attr->driver_version, templen); |
1673 | templen = fc_roundup(templen, sizeof(u32)); | 1736 | templen = fc_roundup(templen, sizeof(u32)); |
1674 | curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; | 1737 | curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; |
1675 | len += templen;; | 1738 | len += templen; |
1676 | count++; | 1739 | count++; |
1677 | attr->len = cpu_to_be16(templen + sizeof(attr->type) + | 1740 | attr->len = cpu_to_be16(templen + sizeof(attr->type) + |
1678 | sizeof(templen)); | 1741 | sizeof(templen)); |
@@ -4918,6 +4981,7 @@ enum bfa_fcs_vport_event { | |||
4918 | BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */ | 4981 | BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */ |
4919 | BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ | 4982 | BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ |
4920 | BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ | 4983 | BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ |
4984 | BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */ | ||
4921 | }; | 4985 | }; |
4922 | 4986 | ||
4923 | static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, | 4987 | static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, |
@@ -4940,6 +5004,10 @@ static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, | |||
4940 | enum bfa_fcs_vport_event event); | 5004 | enum bfa_fcs_vport_event event); |
4941 | static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, | 5005 | static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, |
4942 | enum bfa_fcs_vport_event event); | 5006 | enum bfa_fcs_vport_event event); |
5007 | static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, | ||
5008 | enum bfa_fcs_vport_event event); | ||
5009 | static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, | ||
5010 | enum bfa_fcs_vport_event event); | ||
4943 | 5011 | ||
4944 | static struct bfa_sm_table_s vport_sm_table[] = { | 5012 | static struct bfa_sm_table_s vport_sm_table[] = { |
4945 | {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT}, | 5013 | {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT}, |
@@ -5042,6 +5110,11 @@ bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, | |||
5042 | bfa_fcs_vport_do_fdisc(vport); | 5110 | bfa_fcs_vport_do_fdisc(vport); |
5043 | break; | 5111 | break; |
5044 | 5112 | ||
5113 | case BFA_FCS_VPORT_SM_STOP: | ||
5114 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); | ||
5115 | bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); | ||
5116 | break; | ||
5117 | |||
5045 | case BFA_FCS_VPORT_SM_OFFLINE: | 5118 | case BFA_FCS_VPORT_SM_OFFLINE: |
5046 | /* | 5119 | /* |
5047 | * This can happen if the vport couldn't be initialzied | 5120 | * This can happen if the vport couldn't be initialzied |
@@ -5155,6 +5228,11 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, | |||
5155 | bfa_fcs_lport_delete(&vport->lport); | 5228 | bfa_fcs_lport_delete(&vport->lport); |
5156 | break; | 5229 | break; |
5157 | 5230 | ||
5231 | case BFA_FCS_VPORT_SM_STOP: | ||
5232 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping); | ||
5233 | bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); | ||
5234 | break; | ||
5235 | |||
5158 | case BFA_FCS_VPORT_SM_OFFLINE: | 5236 | case BFA_FCS_VPORT_SM_OFFLINE: |
5159 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); | 5237 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); |
5160 | bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); | 5238 | bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); |
@@ -5167,6 +5245,32 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, | |||
5167 | } | 5245 | } |
5168 | 5246 | ||
5169 | /* | 5247 | /* |
5248 | * Vport is being stopped - awaiting lport stop completion to send | ||
5249 | * LOGO to fabric. | ||
5250 | */ | ||
5251 | static void | ||
5252 | bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, | ||
5253 | enum bfa_fcs_vport_event event) | ||
5254 | { | ||
5255 | bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); | ||
5256 | bfa_trc(__vport_fcs(vport), event); | ||
5257 | |||
5258 | switch (event) { | ||
5259 | case BFA_FCS_VPORT_SM_STOPCOMP: | ||
5260 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop); | ||
5261 | bfa_fcs_vport_do_logo(vport); | ||
5262 | break; | ||
5263 | |||
5264 | case BFA_FCS_VPORT_SM_OFFLINE: | ||
5265 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); | ||
5266 | break; | ||
5267 | |||
5268 | default: | ||
5269 | bfa_sm_fault(__vport_fcs(vport), event); | ||
5270 | } | ||
5271 | } | ||
5272 | |||
5273 | /* | ||
5170 | * Vport is being deleted - awaiting lport delete completion to send | 5274 | * Vport is being deleted - awaiting lport delete completion to send |
5171 | * LOGO to fabric. | 5275 | * LOGO to fabric. |
5172 | */ | 5276 | */ |
@@ -5236,6 +5340,10 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, | |||
5236 | bfa_fcs_vport_free(vport); | 5340 | bfa_fcs_vport_free(vport); |
5237 | break; | 5341 | break; |
5238 | 5342 | ||
5343 | case BFA_FCS_VPORT_SM_STOPCOMP: | ||
5344 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); | ||
5345 | break; | ||
5346 | |||
5239 | case BFA_FCS_VPORT_SM_DELETE: | 5347 | case BFA_FCS_VPORT_SM_DELETE: |
5240 | break; | 5348 | break; |
5241 | 5349 | ||
@@ -5245,6 +5353,34 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, | |||
5245 | } | 5353 | } |
5246 | 5354 | ||
5247 | /* | 5355 | /* |
5356 | * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup | ||
5357 | * is done. | ||
5358 | */ | ||
5359 | static void | ||
5360 | bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, | ||
5361 | enum bfa_fcs_vport_event event) | ||
5362 | { | ||
5363 | bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); | ||
5364 | bfa_trc(__vport_fcs(vport), event); | ||
5365 | |||
5366 | switch (event) { | ||
5367 | case BFA_FCS_VPORT_SM_OFFLINE: | ||
5368 | bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); | ||
5369 | /* | ||
5370 | * !!! fall through !!! | ||
5371 | */ | ||
5372 | |||
5373 | case BFA_FCS_VPORT_SM_RSP_OK: | ||
5374 | case BFA_FCS_VPORT_SM_RSP_ERROR: | ||
5375 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); | ||
5376 | break; | ||
5377 | |||
5378 | default: | ||
5379 | bfa_sm_fault(__vport_fcs(vport), event); | ||
5380 | } | ||
5381 | } | ||
5382 | |||
5383 | /* | ||
5248 | * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup | 5384 | * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup |
5249 | * is done. | 5385 | * is done. |
5250 | */ | 5386 | */ |
@@ -5422,6 +5558,15 @@ bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport) | |||
5422 | } | 5558 | } |
5423 | 5559 | ||
5424 | /* | 5560 | /* |
5561 | * Stop completion callback from associated lport | ||
5562 | */ | ||
5563 | void | ||
5564 | bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport) | ||
5565 | { | ||
5566 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP); | ||
5567 | } | ||
5568 | |||
5569 | /* | ||
5425 | * Delete completion callback from associated lport | 5570 | * Delete completion callback from associated lport |
5426 | */ | 5571 | */ |
5427 | void | 5572 | void |