diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-06-17 20:56:36 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-06-17 23:05:45 -0400 |
commit | 2e0fef85e098f6794956b8b80b111179fbb4cbb7 (patch) | |
tree | f632090be67f95e9a637eeb044938ba1591e848f /drivers/scsi/lpfc | |
parent | 4c2baaaf2ba4875d1d2d59b3b3e1216d3277b17a (diff) |
[SCSI] lpfc: NPIV: split ports
The driver is reorganized to separate the handling of the adapter from
the handling of the FC port. Adapter handling includes submissions of
command requests, receiving responses, and managing adapter resources.
The FC port includes the discovery engine, login handling, and the
mapping of a Scsi_Host on the "port". Although not a large functional
change, as it touches core structures and functions, resulting in a
large text delta.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 235 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 443 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 105 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 225 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_disc.h | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 1431 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 1245 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 23 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 576 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 39 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mem.c | 31 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 988 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 119 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.h | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 727 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.h | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_version.h | 2 |
17 files changed, 3243 insertions, 2959 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 82e8f90c461..8d718964f28 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -19,6 +19,8 @@ | |||
19 | * included with this package. * | 19 | * included with this package. * |
20 | *******************************************************************/ | 20 | *******************************************************************/ |
21 | 21 | ||
22 | #include <scsi/scsi_host.h> | ||
23 | |||
22 | struct lpfc_sli2_slim; | 24 | struct lpfc_sli2_slim; |
23 | 25 | ||
24 | 26 | ||
@@ -165,48 +167,143 @@ struct lpfc_sysfs_mbox { | |||
165 | struct lpfcMboxq * mbox; | 167 | struct lpfcMboxq * mbox; |
166 | }; | 168 | }; |
167 | 169 | ||
170 | struct lpfc_hba; | ||
171 | |||
172 | enum discovery_state { | ||
173 | LPFC_STATE_UNKNOWN = 0, /* HBA state is unknown */ | ||
174 | LPFC_LOCAL_CFG_LINK = 6, /* local NPORT Id configured */ | ||
175 | LPFC_FLOGI = 7, /* FLOGI sent to Fabric */ | ||
176 | LPFC_FABRIC_CFG_LINK = 8, /* Fabric assigned NPORT Id | ||
177 | * configured */ | ||
178 | LPFC_NS_REG = 9, /* Register with NameServer */ | ||
179 | LPFC_NS_QRY = 10, /* Query NameServer for NPort ID list */ | ||
180 | LPFC_BUILD_DISC_LIST = 11, /* Build ADISC and PLOGI lists for | ||
181 | * device authentication / discovery */ | ||
182 | LPFC_DISC_AUTH = 12, /* Processing ADISC list */ | ||
183 | LPFC_VPORT_READY = 32, | ||
184 | }; | ||
185 | |||
186 | enum hba_state { | ||
187 | LPFC_LINK_UNKNOWN = 0, /* HBA state is unknown */ | ||
188 | LPFC_WARM_START = 1, /* HBA state after selective reset */ | ||
189 | LPFC_INIT_START = 2, /* Initial state after board reset */ | ||
190 | LPFC_INIT_MBX_CMDS = 3, /* Initialize HBA with mbox commands */ | ||
191 | LPFC_LINK_DOWN = 4, /* HBA initialized, link is down */ | ||
192 | LPFC_LINK_UP = 5, /* Link is up - issue READ_LA */ | ||
193 | LPFC_CLEAR_LA = 13, /* authentication cmplt - issue | ||
194 | * CLEAR_LA */ | ||
195 | LPFC_HBA_ERROR = -1 | ||
196 | }; | ||
197 | |||
198 | struct lpfc_vport { | ||
199 | struct list_head listentry; | ||
200 | struct lpfc_hba *phba; | ||
201 | uint8_t port_type; | ||
202 | #define LPFC_PHYSICAL_PORT 1 | ||
203 | #define LPFC_NPIV_PORT 2 | ||
204 | #define LPFC_FABRIC_PORT 3 | ||
205 | enum discovery_state port_state; | ||
206 | |||
207 | |||
208 | uint32_t fc_flag; /* FC flags */ | ||
209 | /* Several of these flags are HBA centric and should be moved to | ||
210 | * phba->link_flag (e.g. FC_PTP, FC_PUBLIC_LOOP) | ||
211 | */ | ||
212 | #define FC_PT2PT 0x1 /* pt2pt with no fabric */ | ||
213 | #define FC_PT2PT_PLOGI 0x2 /* pt2pt initiate PLOGI */ | ||
214 | #define FC_DISC_TMO 0x4 /* Discovery timer running */ | ||
215 | #define FC_PUBLIC_LOOP 0x8 /* Public loop */ | ||
216 | #define FC_LBIT 0x10 /* LOGIN bit in loopinit set */ | ||
217 | #define FC_RSCN_MODE 0x20 /* RSCN cmd rcv'ed */ | ||
218 | #define FC_NLP_MORE 0x40 /* More node to process in node tbl */ | ||
219 | #define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ | ||
220 | #define FC_FABRIC 0x100 /* We are fabric attached */ | ||
221 | #define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */ | ||
222 | #define FC_RSCN_DISCOVERY 0x400 /* Authenticate all devices after RSCN*/ | ||
223 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ | ||
224 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ | ||
225 | #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ | ||
226 | #define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ | ||
227 | |||
228 | struct list_head fc_nodes; | ||
229 | |||
230 | /* Keep counters for the number of entries in each list. */ | ||
231 | uint16_t fc_plogi_cnt; | ||
232 | uint16_t fc_adisc_cnt; | ||
233 | uint16_t fc_reglogin_cnt; | ||
234 | uint16_t fc_prli_cnt; | ||
235 | uint16_t fc_unmap_cnt; | ||
236 | uint16_t fc_map_cnt; | ||
237 | uint16_t fc_npr_cnt; | ||
238 | uint16_t fc_unused_cnt; | ||
239 | struct serv_parm fc_sparam; /* buffer for our service parameters */ | ||
240 | |||
241 | uint32_t fc_myDID; /* fibre channel S_ID */ | ||
242 | uint32_t fc_prevDID; /* previous fibre channel S_ID */ | ||
243 | |||
244 | int32_t stopped; /* HBA has not been restarted since last ERATT */ | ||
245 | uint8_t fc_linkspeed; /* Link speed after last READ_LA */ | ||
246 | |||
247 | uint32_t num_disc_nodes; /*in addition to hba_state */ | ||
248 | |||
249 | uint32_t fc_nlp_cnt; /* outstanding NODELIST requests */ | ||
250 | uint32_t fc_rscn_id_cnt; /* count of RSCNs payloads in list */ | ||
251 | struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN]; | ||
252 | struct lpfc_name fc_nodename; /* fc nodename */ | ||
253 | struct lpfc_name fc_portname; /* fc portname */ | ||
254 | |||
255 | struct lpfc_work_evt disc_timeout_evt; | ||
256 | |||
257 | struct timer_list fc_disctmo; /* Discovery rescue timer */ | ||
258 | uint8_t fc_ns_retry; /* retries for fabric nameserver */ | ||
259 | uint32_t fc_prli_sent; /* cntr for outstanding PRLIs */ | ||
260 | |||
261 | spinlock_t work_port_lock; | ||
262 | uint32_t work_port_events; /* Timeout to be handled */ | ||
263 | #define WORKER_DISC_TMO 0x1 /* Discovery timeout */ | ||
264 | #define WORKER_ELS_TMO 0x2 /* ELS timeout */ | ||
265 | #define WORKER_MBOX_TMO 0x4 /* MBOX timeout */ | ||
266 | #define WORKER_FDMI_TMO 0x8 /* FDMI timeout */ | ||
267 | |||
268 | struct timer_list fc_fdmitmo; | ||
269 | struct timer_list els_tmofunc; | ||
270 | |||
271 | int unreg_vpi_cmpl; | ||
272 | |||
273 | uint8_t load_flag; | ||
274 | #define FC_LOADING 0x1 /* HBA in process of loading drvr */ | ||
275 | #define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */ | ||
276 | |||
277 | }; | ||
278 | |||
168 | struct lpfc_hba { | 279 | struct lpfc_hba { |
169 | struct lpfc_sli sli; | 280 | struct lpfc_sli sli; |
281 | |||
282 | enum hba_state link_state; | ||
283 | uint32_t link_flag; /* link state flags */ | ||
284 | #define LS_LOOPBACK_MODE 0x40000 /* NPort is in Loopback mode */ | ||
285 | /* This flag is set while issuing */ | ||
286 | /* INIT_LINK mailbox command */ | ||
287 | #define LS_IGNORE_ERATT 0x80000 /* intr handler should ignore ERATT */ | ||
288 | |||
289 | uint32_t pgpOffset; /* PGP offset within host memory */ | ||
290 | |||
170 | struct lpfc_sli2_slim *slim2p; | 291 | struct lpfc_sli2_slim *slim2p; |
292 | struct lpfc_dmabuf hbqslimp; | ||
293 | |||
171 | dma_addr_t slim2p_mapping; | 294 | dma_addr_t slim2p_mapping; |
295 | |||
296 | |||
172 | uint16_t pci_cfg_value; | 297 | uint16_t pci_cfg_value; |
173 | 298 | ||
174 | int32_t hba_state; | ||
175 | |||
176 | #define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */ | ||
177 | #define LPFC_WARM_START 1 /* HBA state after selective reset */ | ||
178 | #define LPFC_INIT_START 2 /* Initial state after board reset */ | ||
179 | #define LPFC_INIT_MBX_CMDS 3 /* Initialize HBA with mbox commands */ | ||
180 | #define LPFC_LINK_DOWN 4 /* HBA initialized, link is down */ | ||
181 | #define LPFC_LINK_UP 5 /* Link is up - issue READ_LA */ | ||
182 | #define LPFC_LOCAL_CFG_LINK 6 /* local NPORT Id configured */ | ||
183 | #define LPFC_FLOGI 7 /* FLOGI sent to Fabric */ | ||
184 | #define LPFC_FABRIC_CFG_LINK 8 /* Fabric assigned NPORT Id | ||
185 | configured */ | ||
186 | #define LPFC_NS_REG 9 /* Register with NameServer */ | ||
187 | #define LPFC_NS_QRY 10 /* Query NameServer for NPort ID list */ | ||
188 | #define LPFC_BUILD_DISC_LIST 11 /* Build ADISC and PLOGI lists for | ||
189 | * device authentication / discovery */ | ||
190 | #define LPFC_DISC_AUTH 12 /* Processing ADISC list */ | ||
191 | #define LPFC_CLEAR_LA 13 /* authentication cmplt - issue | ||
192 | CLEAR_LA */ | ||
193 | #define LPFC_HBA_READY 32 | ||
194 | #define LPFC_HBA_ERROR -1 | ||
195 | 299 | ||
196 | int32_t stopped; /* HBA has not been restarted since last ERATT */ | ||
197 | uint8_t fc_linkspeed; /* Link speed after last READ_LA */ | 300 | uint8_t fc_linkspeed; /* Link speed after last READ_LA */ |
198 | 301 | ||
199 | uint32_t fc_eventTag; /* event tag for link attention */ | 302 | uint32_t fc_eventTag; /* event tag for link attention */ |
200 | uint32_t fc_prli_sent; /* cntr for outstanding PRLIs */ | ||
201 | 303 | ||
202 | uint32_t num_disc_nodes; /*in addition to hba_state */ | ||
203 | 304 | ||
204 | struct timer_list fc_estabtmo; /* link establishment timer */ | 305 | struct timer_list fc_estabtmo; /* link establishment timer */ |
205 | struct timer_list fc_disctmo; /* Discovery rescue timer */ | ||
206 | struct timer_list fc_fdmitmo; /* fdmi timer */ | ||
207 | /* These fields used to be binfo */ | 306 | /* These fields used to be binfo */ |
208 | struct lpfc_name fc_nodename; /* fc nodename */ | ||
209 | struct lpfc_name fc_portname; /* fc portname */ | ||
210 | uint32_t fc_pref_DID; /* preferred D_ID */ | 307 | uint32_t fc_pref_DID; /* preferred D_ID */ |
211 | uint8_t fc_pref_ALPA; /* preferred AL_PA */ | 308 | uint8_t fc_pref_ALPA; /* preferred AL_PA */ |
212 | uint32_t fc_edtov; /* E_D_TOV timer value */ | 309 | uint32_t fc_edtov; /* E_D_TOV timer value */ |
@@ -216,61 +313,21 @@ struct lpfc_hba { | |||
216 | uint32_t fc_altov; /* AL_TOV timer value */ | 313 | uint32_t fc_altov; /* AL_TOV timer value */ |
217 | uint32_t fc_crtov; /* C_R_TOV timer value */ | 314 | uint32_t fc_crtov; /* C_R_TOV timer value */ |
218 | uint32_t fc_citov; /* C_I_TOV timer value */ | 315 | uint32_t fc_citov; /* C_I_TOV timer value */ |
219 | uint32_t fc_myDID; /* fibre channel S_ID */ | ||
220 | uint32_t fc_prevDID; /* previous fibre channel S_ID */ | ||
221 | 316 | ||
222 | struct serv_parm fc_sparam; /* buffer for our service parameters */ | ||
223 | struct serv_parm fc_fabparam; /* fabric service parameters buffer */ | 317 | struct serv_parm fc_fabparam; /* fabric service parameters buffer */ |
224 | uint8_t alpa_map[128]; /* AL_PA map from READ_LA */ | 318 | uint8_t alpa_map[128]; /* AL_PA map from READ_LA */ |
225 | 319 | ||
226 | uint8_t fc_ns_retry; /* retries for fabric nameserver */ | ||
227 | uint32_t fc_nlp_cnt; /* outstanding NODELIST requests */ | ||
228 | uint32_t fc_rscn_id_cnt; /* count of RSCNs payloads in list */ | ||
229 | struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN]; | ||
230 | uint32_t lmt; | 320 | uint32_t lmt; |
231 | uint32_t fc_flag; /* FC flags */ | ||
232 | #define FC_PT2PT 0x1 /* pt2pt with no fabric */ | ||
233 | #define FC_PT2PT_PLOGI 0x2 /* pt2pt initiate PLOGI */ | ||
234 | #define FC_DISC_TMO 0x4 /* Discovery timer running */ | ||
235 | #define FC_PUBLIC_LOOP 0x8 /* Public loop */ | ||
236 | #define FC_LBIT 0x10 /* LOGIN bit in loopinit set */ | ||
237 | #define FC_RSCN_MODE 0x20 /* RSCN cmd rcv'ed */ | ||
238 | #define FC_NLP_MORE 0x40 /* More node to process in node tbl */ | ||
239 | #define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ | ||
240 | #define FC_FABRIC 0x100 /* We are fabric attached */ | ||
241 | #define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */ | ||
242 | #define FC_RSCN_DISCOVERY 0x400 /* Authenticate all devices after RSCN*/ | ||
243 | #define FC_BLOCK_MGMT_IO 0x800 /* Don't allow mgmt mbx or iocb cmds */ | ||
244 | #define FC_LOADING 0x1000 /* HBA in process of loading drvr */ | ||
245 | #define FC_UNLOADING 0x2000 /* HBA in process of unloading drvr */ | ||
246 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ | ||
247 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ | ||
248 | #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ | ||
249 | #define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ | ||
250 | #define FC_LOOPBACK_MODE 0x40000 /* NPort is in Loopback mode */ | ||
251 | /* This flag is set while issuing */ | ||
252 | /* INIT_LINK mailbox command */ | ||
253 | #define FC_IGNORE_ERATT 0x80000 /* intr handler should ignore ERATT */ | ||
254 | 321 | ||
255 | uint32_t fc_topology; /* link topology, from LINK INIT */ | 322 | uint32_t fc_topology; /* link topology, from LINK INIT */ |
256 | 323 | ||
257 | struct lpfc_stats fc_stat; | 324 | struct lpfc_stats fc_stat; |
258 | 325 | ||
259 | struct list_head fc_nodes; | ||
260 | |||
261 | /* Keep counters for the number of entries in each list. */ | ||
262 | uint16_t fc_plogi_cnt; | ||
263 | uint16_t fc_adisc_cnt; | ||
264 | uint16_t fc_reglogin_cnt; | ||
265 | uint16_t fc_prli_cnt; | ||
266 | uint16_t fc_unmap_cnt; | ||
267 | uint16_t fc_map_cnt; | ||
268 | uint16_t fc_npr_cnt; | ||
269 | uint16_t fc_unused_cnt; | ||
270 | struct lpfc_nodelist fc_fcpnodev; /* nodelist entry for no device */ | 326 | struct lpfc_nodelist fc_fcpnodev; /* nodelist entry for no device */ |
271 | uint32_t nport_event_cnt; /* timestamp for nlplist entry */ | 327 | uint32_t nport_event_cnt; /* timestamp for nlplist entry */ |
272 | 328 | ||
273 | uint32_t wwnn[2]; | 329 | uint8_t wwnn[8]; |
330 | uint8_t wwpn[8]; | ||
274 | uint32_t RandomData[7]; | 331 | uint32_t RandomData[7]; |
275 | 332 | ||
276 | uint32_t cfg_log_verbose; | 333 | uint32_t cfg_log_verbose; |
@@ -304,18 +361,12 @@ struct lpfc_hba { | |||
304 | 361 | ||
305 | lpfc_vpd_t vpd; /* vital product data */ | 362 | lpfc_vpd_t vpd; /* vital product data */ |
306 | 363 | ||
307 | struct Scsi_Host *host; | ||
308 | struct pci_dev *pcidev; | 364 | struct pci_dev *pcidev; |
309 | struct list_head work_list; | 365 | struct list_head work_list; |
310 | uint32_t work_ha; /* Host Attention Bits for WT */ | 366 | uint32_t work_ha; /* Host Attention Bits for WT */ |
311 | uint32_t work_ha_mask; /* HA Bits owned by WT */ | 367 | uint32_t work_ha_mask; /* HA Bits owned by WT */ |
312 | uint32_t work_hs; /* HS stored in case of ERRAT */ | 368 | uint32_t work_hs; /* HS stored in case of ERRAT */ |
313 | uint32_t work_status[2]; /* Extra status from SLIM */ | 369 | uint32_t work_status[2]; /* Extra status from SLIM */ |
314 | uint32_t work_hba_events; /* Timeout to be handled */ | ||
315 | #define WORKER_DISC_TMO 0x1 /* Discovery timeout */ | ||
316 | #define WORKER_ELS_TMO 0x2 /* ELS timeout */ | ||
317 | #define WORKER_MBOX_TMO 0x4 /* MBOX timeout */ | ||
318 | #define WORKER_FDMI_TMO 0x8 /* FDMI timeout */ | ||
319 | 370 | ||
320 | wait_queue_head_t *work_wait; | 371 | wait_queue_head_t *work_wait; |
321 | struct task_struct *worker_thread; | 372 | struct task_struct *worker_thread; |
@@ -353,7 +404,6 @@ struct lpfc_hba { | |||
353 | uint8_t soft_wwn_enable; | 404 | uint8_t soft_wwn_enable; |
354 | 405 | ||
355 | struct timer_list fcp_poll_timer; | 406 | struct timer_list fcp_poll_timer; |
356 | struct timer_list els_tmofunc; | ||
357 | 407 | ||
358 | /* | 408 | /* |
359 | * stat counters | 409 | * stat counters |
@@ -370,6 +420,7 @@ struct lpfc_hba { | |||
370 | uint32_t total_scsi_bufs; | 420 | uint32_t total_scsi_bufs; |
371 | struct list_head lpfc_iocb_list; | 421 | struct list_head lpfc_iocb_list; |
372 | uint32_t total_iocbq_bufs; | 422 | uint32_t total_iocbq_bufs; |
423 | spinlock_t hbalock; | ||
373 | 424 | ||
374 | /* pci_mem_pools */ | 425 | /* pci_mem_pools */ |
375 | struct pci_pool *lpfc_scsi_dma_buf_pool; | 426 | struct pci_pool *lpfc_scsi_dma_buf_pool; |
@@ -380,21 +431,33 @@ struct lpfc_hba { | |||
380 | mempool_t *nlp_mem_pool; | 431 | mempool_t *nlp_mem_pool; |
381 | 432 | ||
382 | struct fc_host_statistics link_stats; | 433 | struct fc_host_statistics link_stats; |
434 | struct list_head port_list; | ||
435 | struct lpfc_vport *pport; /* physical lpfc_vport pointer */ | ||
383 | }; | 436 | }; |
384 | 437 | ||
438 | static inline struct Scsi_Host * | ||
439 | lpfc_shost_from_vport(struct lpfc_vport *vport) | ||
440 | { | ||
441 | return container_of((void *) vport, struct Scsi_Host, hostdata[0]); | ||
442 | } | ||
443 | |||
385 | static inline void | 444 | static inline void |
386 | lpfc_set_loopback_flag(struct lpfc_hba *phba) { | 445 | lpfc_set_loopback_flag(struct lpfc_hba *phba) |
446 | { | ||
387 | if (phba->cfg_topology == FLAGS_LOCAL_LB) | 447 | if (phba->cfg_topology == FLAGS_LOCAL_LB) |
388 | phba->fc_flag |= FC_LOOPBACK_MODE; | 448 | phba->link_flag |= LS_LOOPBACK_MODE; |
389 | else | 449 | else |
390 | phba->fc_flag &= ~FC_LOOPBACK_MODE; | 450 | phba->link_flag &= ~LS_LOOPBACK_MODE; |
451 | } | ||
452 | |||
453 | static inline int | ||
454 | lpfc_is_link_up(struct lpfc_hba *phba) | ||
455 | { | ||
456 | return phba->link_state == LPFC_LINK_UP || | ||
457 | phba->link_state == LPFC_CLEAR_LA; | ||
391 | } | 458 | } |
392 | 459 | ||
393 | struct rnidrsp { | 460 | |
394 | void *buf; | ||
395 | uint32_t uniqueid; | ||
396 | struct list_head list; | ||
397 | uint32_t data; | ||
398 | }; | ||
399 | 461 | ||
400 | #define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */ | 462 | #define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */ |
463 | |||
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 95fe77e816f..b8adff8cea6 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -76,55 +76,68 @@ static ssize_t | |||
76 | lpfc_info_show(struct class_device *cdev, char *buf) | 76 | lpfc_info_show(struct class_device *cdev, char *buf) |
77 | { | 77 | { |
78 | struct Scsi_Host *host = class_to_shost(cdev); | 78 | struct Scsi_Host *host = class_to_shost(cdev); |
79 | |||
79 | return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host)); | 80 | return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host)); |
80 | } | 81 | } |
81 | 82 | ||
82 | static ssize_t | 83 | static ssize_t |
83 | lpfc_serialnum_show(struct class_device *cdev, char *buf) | 84 | lpfc_serialnum_show(struct class_device *cdev, char *buf) |
84 | { | 85 | { |
85 | struct Scsi_Host *host = class_to_shost(cdev); | 86 | struct Scsi_Host *shost = class_to_shost(cdev); |
86 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 87 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
88 | struct lpfc_hba *phba = vport->phba; | ||
89 | |||
87 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber); | 90 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber); |
88 | } | 91 | } |
89 | 92 | ||
90 | static ssize_t | 93 | static ssize_t |
91 | lpfc_modeldesc_show(struct class_device *cdev, char *buf) | 94 | lpfc_modeldesc_show(struct class_device *cdev, char *buf) |
92 | { | 95 | { |
93 | struct Scsi_Host *host = class_to_shost(cdev); | 96 | struct Scsi_Host *shost = class_to_shost(cdev); |
94 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 97 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
98 | struct lpfc_hba *phba = vport->phba; | ||
99 | |||
95 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc); | 100 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc); |
96 | } | 101 | } |
97 | 102 | ||
98 | static ssize_t | 103 | static ssize_t |
99 | lpfc_modelname_show(struct class_device *cdev, char *buf) | 104 | lpfc_modelname_show(struct class_device *cdev, char *buf) |
100 | { | 105 | { |
101 | struct Scsi_Host *host = class_to_shost(cdev); | 106 | struct Scsi_Host *shost = class_to_shost(cdev); |
102 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 107 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
108 | struct lpfc_hba *phba = vport->phba; | ||
109 | |||
103 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName); | 110 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName); |
104 | } | 111 | } |
105 | 112 | ||
106 | static ssize_t | 113 | static ssize_t |
107 | lpfc_programtype_show(struct class_device *cdev, char *buf) | 114 | lpfc_programtype_show(struct class_device *cdev, char *buf) |
108 | { | 115 | { |
109 | struct Scsi_Host *host = class_to_shost(cdev); | 116 | struct Scsi_Host *shost = class_to_shost(cdev); |
110 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 117 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
118 | struct lpfc_hba *phba = vport->phba; | ||
119 | |||
111 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType); | 120 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType); |
112 | } | 121 | } |
113 | 122 | ||
114 | static ssize_t | 123 | static ssize_t |
115 | lpfc_portnum_show(struct class_device *cdev, char *buf) | 124 | lpfc_vportnum_show(struct class_device *cdev, char *buf) |
116 | { | 125 | { |
117 | struct Scsi_Host *host = class_to_shost(cdev); | 126 | struct Scsi_Host *shost = class_to_shost(cdev); |
118 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 127 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
128 | struct lpfc_hba *phba = vport->phba; | ||
129 | |||
119 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port); | 130 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port); |
120 | } | 131 | } |
121 | 132 | ||
122 | static ssize_t | 133 | static ssize_t |
123 | lpfc_fwrev_show(struct class_device *cdev, char *buf) | 134 | lpfc_fwrev_show(struct class_device *cdev, char *buf) |
124 | { | 135 | { |
125 | struct Scsi_Host *host = class_to_shost(cdev); | 136 | struct Scsi_Host *shost = class_to_shost(cdev); |
126 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 137 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
138 | struct lpfc_hba *phba = vport->phba; | ||
127 | char fwrev[32]; | 139 | char fwrev[32]; |
140 | |||
128 | lpfc_decode_firmware_rev(phba, fwrev, 1); | 141 | lpfc_decode_firmware_rev(phba, fwrev, 1); |
129 | return snprintf(buf, PAGE_SIZE, "%s\n",fwrev); | 142 | return snprintf(buf, PAGE_SIZE, "%s\n",fwrev); |
130 | } | 143 | } |
@@ -133,59 +146,80 @@ static ssize_t | |||
133 | lpfc_hdw_show(struct class_device *cdev, char *buf) | 146 | lpfc_hdw_show(struct class_device *cdev, char *buf) |
134 | { | 147 | { |
135 | char hdw[9]; | 148 | char hdw[9]; |
136 | struct Scsi_Host *host = class_to_shost(cdev); | 149 | struct Scsi_Host *shost = class_to_shost(cdev); |
137 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 150 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
151 | struct lpfc_hba *phba = vport->phba; | ||
138 | lpfc_vpd_t *vp = &phba->vpd; | 152 | lpfc_vpd_t *vp = &phba->vpd; |
153 | |||
139 | lpfc_jedec_to_ascii(vp->rev.biuRev, hdw); | 154 | lpfc_jedec_to_ascii(vp->rev.biuRev, hdw); |
140 | return snprintf(buf, PAGE_SIZE, "%s\n", hdw); | 155 | return snprintf(buf, PAGE_SIZE, "%s\n", hdw); |
141 | } | 156 | } |
142 | static ssize_t | 157 | static ssize_t |
143 | lpfc_option_rom_version_show(struct class_device *cdev, char *buf) | 158 | lpfc_option_rom_version_show(struct class_device *cdev, char *buf) |
144 | { | 159 | { |
145 | struct Scsi_Host *host = class_to_shost(cdev); | 160 | struct Scsi_Host *shost = class_to_shost(cdev); |
146 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 161 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
162 | struct lpfc_hba *phba = vport->phba; | ||
163 | |||
147 | return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion); | 164 | return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion); |
148 | } | 165 | } |
149 | static ssize_t | 166 | static ssize_t |
150 | lpfc_state_show(struct class_device *cdev, char *buf) | 167 | lpfc_state_show(struct class_device *cdev, char *buf) |
151 | { | 168 | { |
152 | struct Scsi_Host *host = class_to_shost(cdev); | 169 | struct Scsi_Host *shost = class_to_shost(cdev); |
153 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 170 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
154 | int len = 0; | 171 | struct lpfc_hba *phba = vport->phba; |
155 | switch (phba->hba_state) { | 172 | int len = 0; |
156 | case LPFC_STATE_UNKNOWN: | 173 | |
174 | switch (phba->link_state) { | ||
175 | case LPFC_LINK_UNKNOWN: | ||
157 | case LPFC_WARM_START: | 176 | case LPFC_WARM_START: |
158 | case LPFC_INIT_START: | 177 | case LPFC_INIT_START: |
159 | case LPFC_INIT_MBX_CMDS: | 178 | case LPFC_INIT_MBX_CMDS: |
160 | case LPFC_LINK_DOWN: | 179 | case LPFC_LINK_DOWN: |
161 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Down\n"); | 180 | case LPFC_HBA_ERROR: |
181 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Down"); | ||
162 | break; | 182 | break; |
163 | case LPFC_LINK_UP: | 183 | case LPFC_LINK_UP: |
164 | case LPFC_LOCAL_CFG_LINK: | ||
165 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Up\n"); | ||
166 | break; | ||
167 | case LPFC_FLOGI: | ||
168 | case LPFC_FABRIC_CFG_LINK: | ||
169 | case LPFC_NS_REG: | ||
170 | case LPFC_NS_QRY: | ||
171 | case LPFC_BUILD_DISC_LIST: | ||
172 | case LPFC_DISC_AUTH: | ||
173 | case LPFC_CLEAR_LA: | 184 | case LPFC_CLEAR_LA: |
174 | len += snprintf(buf + len, PAGE_SIZE-len, | 185 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Up - \n"); |
175 | "Link Up - Discovery\n"); | 186 | |
176 | break; | 187 | switch (vport->port_state) { |
177 | case LPFC_HBA_READY: | 188 | len += snprintf(buf + len, PAGE_SIZE-len, |
178 | len += snprintf(buf + len, PAGE_SIZE-len, | 189 | "initializing\n"); |
179 | "Link Up - Ready:\n"); | 190 | break; |
191 | case LPFC_LOCAL_CFG_LINK: | ||
192 | len += snprintf(buf + len, PAGE_SIZE-len, | ||
193 | "configuring\n"); | ||
194 | break; | ||
195 | case LPFC_FLOGI: | ||
196 | case LPFC_FABRIC_CFG_LINK: | ||
197 | case LPFC_NS_REG: | ||
198 | case LPFC_NS_QRY: | ||
199 | case LPFC_BUILD_DISC_LIST: | ||
200 | case LPFC_DISC_AUTH: | ||
201 | len += snprintf(buf + len, PAGE_SIZE - len, | ||
202 | "Discovery\n"); | ||
203 | break; | ||
204 | case LPFC_VPORT_READY: | ||
205 | len += snprintf(buf + len, PAGE_SIZE - len, "Ready\n"); | ||
206 | break; | ||
207 | |||
208 | case LPFC_STATE_UNKNOWN: | ||
209 | len += snprintf(buf + len, PAGE_SIZE - len, | ||
210 | "Unknown\n"); | ||
211 | break; | ||
212 | } | ||
213 | |||
180 | if (phba->fc_topology == TOPOLOGY_LOOP) { | 214 | if (phba->fc_topology == TOPOLOGY_LOOP) { |
181 | if (phba->fc_flag & FC_PUBLIC_LOOP) | 215 | if (vport->fc_flag & FC_PUBLIC_LOOP) |
182 | len += snprintf(buf + len, PAGE_SIZE-len, | 216 | len += snprintf(buf + len, PAGE_SIZE-len, |
183 | " Public Loop\n"); | 217 | " Public Loop\n"); |
184 | else | 218 | else |
185 | len += snprintf(buf + len, PAGE_SIZE-len, | 219 | len += snprintf(buf + len, PAGE_SIZE-len, |
186 | " Private Loop\n"); | 220 | " Private Loop\n"); |
187 | } else { | 221 | } else { |
188 | if (phba->fc_flag & FC_FABRIC) | 222 | if (vport->fc_flag & FC_FABRIC) |
189 | len += snprintf(buf + len, PAGE_SIZE-len, | 223 | len += snprintf(buf + len, PAGE_SIZE-len, |
190 | " Fabric\n"); | 224 | " Fabric\n"); |
191 | else | 225 | else |
@@ -193,29 +227,32 @@ lpfc_state_show(struct class_device *cdev, char *buf) | |||
193 | " Point-2-Point\n"); | 227 | " Point-2-Point\n"); |
194 | } | 228 | } |
195 | } | 229 | } |
230 | |||
196 | return len; | 231 | return len; |
197 | } | 232 | } |
198 | 233 | ||
199 | static ssize_t | 234 | static ssize_t |
200 | lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) | 235 | lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) |
201 | { | 236 | { |
202 | struct Scsi_Host *host = class_to_shost(cdev); | 237 | struct Scsi_Host *shost = class_to_shost(cdev); |
203 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 238 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
204 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt + | 239 | |
205 | phba->fc_unmap_cnt); | 240 | return snprintf(buf, PAGE_SIZE, "%d\n", |
241 | vport->fc_map_cnt + vport->fc_unmap_cnt); | ||
206 | } | 242 | } |
207 | 243 | ||
208 | 244 | ||
209 | static int | 245 | static int |
210 | lpfc_issue_lip(struct Scsi_Host *host) | 246 | lpfc_issue_lip(struct Scsi_Host *shost) |
211 | { | 247 | { |
212 | struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata; | 248 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
249 | struct lpfc_hba *phba = vport->phba; | ||
213 | LPFC_MBOXQ_t *pmboxq; | 250 | LPFC_MBOXQ_t *pmboxq; |
214 | int mbxstatus = MBXERR_ERROR; | 251 | int mbxstatus = MBXERR_ERROR; |
215 | 252 | ||
216 | if ((phba->fc_flag & FC_OFFLINE_MODE) || | 253 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
217 | (phba->fc_flag & FC_BLOCK_MGMT_IO) || | 254 | (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) || |
218 | (phba->hba_state != LPFC_HBA_READY)) | 255 | (vport->port_state != LPFC_VPORT_READY)) |
219 | return -EPERM; | 256 | return -EPERM; |
220 | 257 | ||
221 | pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); | 258 | pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); |
@@ -320,8 +357,10 @@ lpfc_selective_reset(struct lpfc_hba *phba) | |||
320 | static ssize_t | 357 | static ssize_t |
321 | lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count) | 358 | lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count) |
322 | { | 359 | { |
323 | struct Scsi_Host *host = class_to_shost(cdev); | 360 | struct Scsi_Host *shost = class_to_shost(cdev); |
324 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 361 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
362 | struct lpfc_hba *phba = vport->phba; | ||
363 | |||
325 | int status = -EINVAL; | 364 | int status = -EINVAL; |
326 | 365 | ||
327 | if (strncmp(buf, "selective", sizeof("selective") - 1) == 0) | 366 | if (strncmp(buf, "selective", sizeof("selective") - 1) == 0) |
@@ -336,23 +375,26 @@ lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count) | |||
336 | static ssize_t | 375 | static ssize_t |
337 | lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) | 376 | lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) |
338 | { | 377 | { |
339 | struct Scsi_Host *host = class_to_shost(cdev); | 378 | struct Scsi_Host *shost = class_to_shost(cdev); |
340 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 379 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
380 | struct lpfc_hba *phba = vport->phba; | ||
381 | |||
341 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); | 382 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); |
342 | } | 383 | } |
343 | 384 | ||
344 | static ssize_t | 385 | static ssize_t |
345 | lpfc_board_mode_show(struct class_device *cdev, char *buf) | 386 | lpfc_board_mode_show(struct class_device *cdev, char *buf) |
346 | { | 387 | { |
347 | struct Scsi_Host *host = class_to_shost(cdev); | 388 | struct Scsi_Host *shost = class_to_shost(cdev); |
348 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 389 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
390 | struct lpfc_hba *phba = vport->phba; | ||
349 | char * state; | 391 | char * state; |
350 | 392 | ||
351 | if (phba->hba_state == LPFC_HBA_ERROR) | 393 | if (phba->link_state == LPFC_HBA_ERROR) |
352 | state = "error"; | 394 | state = "error"; |
353 | else if (phba->hba_state == LPFC_WARM_START) | 395 | else if (phba->link_state == LPFC_WARM_START) |
354 | state = "warm start"; | 396 | state = "warm start"; |
355 | else if (phba->hba_state == LPFC_INIT_START) | 397 | else if (phba->link_state == LPFC_INIT_START) |
356 | state = "offline"; | 398 | state = "offline"; |
357 | else | 399 | else |
358 | state = "online"; | 400 | state = "online"; |
@@ -363,8 +405,9 @@ lpfc_board_mode_show(struct class_device *cdev, char *buf) | |||
363 | static ssize_t | 405 | static ssize_t |
364 | lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) | 406 | lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) |
365 | { | 407 | { |
366 | struct Scsi_Host *host = class_to_shost(cdev); | 408 | struct Scsi_Host *shost = class_to_shost(cdev); |
367 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 409 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
410 | struct lpfc_hba *phba = vport->phba; | ||
368 | struct completion online_compl; | 411 | struct completion online_compl; |
369 | int status=0; | 412 | int status=0; |
370 | 413 | ||
@@ -392,8 +435,9 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) | |||
392 | static ssize_t | 435 | static ssize_t |
393 | lpfc_poll_show(struct class_device *cdev, char *buf) | 436 | lpfc_poll_show(struct class_device *cdev, char *buf) |
394 | { | 437 | { |
395 | struct Scsi_Host *host = class_to_shost(cdev); | 438 | struct Scsi_Host *shost = class_to_shost(cdev); |
396 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 439 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
440 | struct lpfc_hba *phba = vport->phba; | ||
397 | 441 | ||
398 | return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll); | 442 | return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll); |
399 | } | 443 | } |
@@ -402,8 +446,9 @@ static ssize_t | |||
402 | lpfc_poll_store(struct class_device *cdev, const char *buf, | 446 | lpfc_poll_store(struct class_device *cdev, const char *buf, |
403 | size_t count) | 447 | size_t count) |
404 | { | 448 | { |
405 | struct Scsi_Host *host = class_to_shost(cdev); | 449 | struct Scsi_Host *shost = class_to_shost(cdev); |
406 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 450 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
451 | struct lpfc_hba *phba = vport->phba; | ||
407 | uint32_t creg_val; | 452 | uint32_t creg_val; |
408 | uint32_t old_val; | 453 | uint32_t old_val; |
409 | int val=0; | 454 | int val=0; |
@@ -417,7 +462,7 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, | |||
417 | if ((val & 0x3) != val) | 462 | if ((val & 0x3) != val) |
418 | return -EINVAL; | 463 | return -EINVAL; |
419 | 464 | ||
420 | spin_lock_irq(phba->host->host_lock); | 465 | spin_lock_irq(&phba->hbalock); |
421 | 466 | ||
422 | old_val = phba->cfg_poll; | 467 | old_val = phba->cfg_poll; |
423 | 468 | ||
@@ -432,16 +477,16 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, | |||
432 | lpfc_poll_start_timer(phba); | 477 | lpfc_poll_start_timer(phba); |
433 | } | 478 | } |
434 | } else if (val != 0x0) { | 479 | } else if (val != 0x0) { |
435 | spin_unlock_irq(phba->host->host_lock); | 480 | spin_unlock_irq(&phba->hbalock); |
436 | return -EINVAL; | 481 | return -EINVAL; |
437 | } | 482 | } |
438 | 483 | ||
439 | if (!(val & DISABLE_FCP_RING_INT) && | 484 | if (!(val & DISABLE_FCP_RING_INT) && |
440 | (old_val & DISABLE_FCP_RING_INT)) | 485 | (old_val & DISABLE_FCP_RING_INT)) |
441 | { | 486 | { |
442 | spin_unlock_irq(phba->host->host_lock); | 487 | spin_unlock_irq(&phba->hbalock); |
443 | del_timer(&phba->fcp_poll_timer); | 488 | del_timer(&phba->fcp_poll_timer); |
444 | spin_lock_irq(phba->host->host_lock); | 489 | spin_lock_irq(&phba->hbalock); |
445 | creg_val = readl(phba->HCregaddr); | 490 | creg_val = readl(phba->HCregaddr); |
446 | creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING); | 491 | creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING); |
447 | writel(creg_val, phba->HCregaddr); | 492 | writel(creg_val, phba->HCregaddr); |
@@ -450,7 +495,7 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, | |||
450 | 495 | ||
451 | phba->cfg_poll = val; | 496 | phba->cfg_poll = val; |
452 | 497 | ||
453 | spin_unlock_irq(phba->host->host_lock); | 498 | spin_unlock_irq(&phba->hbalock); |
454 | 499 | ||
455 | return strlen(buf); | 500 | return strlen(buf); |
456 | } | 501 | } |
@@ -459,8 +504,9 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, | |||
459 | static ssize_t \ | 504 | static ssize_t \ |
460 | lpfc_##attr##_show(struct class_device *cdev, char *buf) \ | 505 | lpfc_##attr##_show(struct class_device *cdev, char *buf) \ |
461 | { \ | 506 | { \ |
462 | struct Scsi_Host *host = class_to_shost(cdev);\ | 507 | struct Scsi_Host *shost = class_to_shost(cdev);\ |
463 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ | 508 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ |
509 | struct lpfc_hba *phba = vport->phba;\ | ||
464 | int val = 0;\ | 510 | int val = 0;\ |
465 | val = phba->cfg_##attr;\ | 511 | val = phba->cfg_##attr;\ |
466 | return snprintf(buf, PAGE_SIZE, "%d\n",\ | 512 | return snprintf(buf, PAGE_SIZE, "%d\n",\ |
@@ -471,8 +517,9 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ | |||
471 | static ssize_t \ | 517 | static ssize_t \ |
472 | lpfc_##attr##_show(struct class_device *cdev, char *buf) \ | 518 | lpfc_##attr##_show(struct class_device *cdev, char *buf) \ |
473 | { \ | 519 | { \ |
474 | struct Scsi_Host *host = class_to_shost(cdev);\ | 520 | struct Scsi_Host *shost = class_to_shost(cdev);\ |
475 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ | 521 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ |
522 | struct lpfc_hba *phba = vport->phba;\ | ||
476 | int val = 0;\ | 523 | int val = 0;\ |
477 | val = phba->cfg_##attr;\ | 524 | val = phba->cfg_##attr;\ |
478 | return snprintf(buf, PAGE_SIZE, "%#x\n",\ | 525 | return snprintf(buf, PAGE_SIZE, "%#x\n",\ |
@@ -514,8 +561,9 @@ lpfc_##attr##_set(struct lpfc_hba *phba, int val) \ | |||
514 | static ssize_t \ | 561 | static ssize_t \ |
515 | lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ | 562 | lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ |
516 | { \ | 563 | { \ |
517 | struct Scsi_Host *host = class_to_shost(cdev);\ | 564 | struct Scsi_Host *shost = class_to_shost(cdev);\ |
518 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ | 565 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ |
566 | struct lpfc_hba *phba = vport->phba;\ | ||
519 | int val=0;\ | 567 | int val=0;\ |
520 | if (!isdigit(buf[0]))\ | 568 | if (!isdigit(buf[0]))\ |
521 | return -EINVAL;\ | 569 | return -EINVAL;\ |
@@ -576,7 +624,7 @@ static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL); | |||
576 | static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL); | 624 | static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL); |
577 | static CLASS_DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL); | 625 | static CLASS_DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL); |
578 | static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL); | 626 | static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL); |
579 | static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_portnum_show, NULL); | 627 | static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL); |
580 | static CLASS_DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL); | 628 | static CLASS_DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL); |
581 | static CLASS_DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL); | 629 | static CLASS_DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL); |
582 | static CLASS_DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL); | 630 | static CLASS_DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL); |
@@ -600,8 +648,9 @@ static ssize_t | |||
600 | lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf, | 648 | lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf, |
601 | size_t count) | 649 | size_t count) |
602 | { | 650 | { |
603 | struct Scsi_Host *host = class_to_shost(cdev); | 651 | struct Scsi_Host *shost = class_to_shost(cdev); |
604 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 652 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
653 | struct lpfc_hba *phba = vport->phba; | ||
605 | unsigned int cnt = count; | 654 | unsigned int cnt = count; |
606 | 655 | ||
607 | /* | 656 | /* |
@@ -634,8 +683,10 @@ static CLASS_DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL, | |||
634 | static ssize_t | 683 | static ssize_t |
635 | lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) | 684 | lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) |
636 | { | 685 | { |
637 | struct Scsi_Host *host = class_to_shost(cdev); | 686 | struct Scsi_Host *shost = class_to_shost(cdev); |
638 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 687 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
688 | struct lpfc_hba *phba = vport->phba; | ||
689 | |||
639 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", | 690 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", |
640 | (unsigned long long)phba->cfg_soft_wwpn); | 691 | (unsigned long long)phba->cfg_soft_wwpn); |
641 | } | 692 | } |
@@ -644,8 +695,9 @@ lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) | |||
644 | static ssize_t | 695 | static ssize_t |
645 | lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) | 696 | lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) |
646 | { | 697 | { |
647 | struct Scsi_Host *host = class_to_shost(cdev); | 698 | struct Scsi_Host *shost = class_to_shost(cdev); |
648 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 699 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
700 | struct lpfc_hba *phba = vport->phba; | ||
649 | struct completion online_compl; | 701 | struct completion online_compl; |
650 | int stat1=0, stat2=0; | 702 | int stat1=0, stat2=0; |
651 | unsigned int i, j, cnt=count; | 703 | unsigned int i, j, cnt=count; |
@@ -680,9 +732,9 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) | |||
680 | } | 732 | } |
681 | } | 733 | } |
682 | phba->cfg_soft_wwpn = wwn_to_u64(wwpn); | 734 | phba->cfg_soft_wwpn = wwn_to_u64(wwpn); |
683 | fc_host_port_name(host) = phba->cfg_soft_wwpn; | 735 | fc_host_port_name(shost) = phba->cfg_soft_wwpn; |
684 | if (phba->cfg_soft_wwnn) | 736 | if (phba->cfg_soft_wwnn) |
685 | fc_host_node_name(host) = phba->cfg_soft_wwnn; | 737 | fc_host_node_name(shost) = phba->cfg_soft_wwnn; |
686 | 738 | ||
687 | dev_printk(KERN_NOTICE, &phba->pcidev->dev, | 739 | dev_printk(KERN_NOTICE, &phba->pcidev->dev, |
688 | "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); | 740 | "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); |
@@ -790,8 +842,9 @@ MODULE_PARM_DESC(lpfc_nodev_tmo, | |||
790 | static ssize_t | 842 | static ssize_t |
791 | lpfc_nodev_tmo_show(struct class_device *cdev, char *buf) | 843 | lpfc_nodev_tmo_show(struct class_device *cdev, char *buf) |
792 | { | 844 | { |
793 | struct Scsi_Host *host = class_to_shost(cdev); | 845 | struct Scsi_Host *shost = class_to_shost(cdev); |
794 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 846 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
847 | struct lpfc_hba *phba = vport->phba; | ||
795 | int val = 0; | 848 | int val = 0; |
796 | val = phba->cfg_devloss_tmo; | 849 | val = phba->cfg_devloss_tmo; |
797 | return snprintf(buf, PAGE_SIZE, "%d\n", | 850 | return snprintf(buf, PAGE_SIZE, "%d\n", |
@@ -829,18 +882,6 @@ lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val) | |||
829 | return -EINVAL; | 882 | return -EINVAL; |
830 | } | 883 | } |
831 | 884 | ||
832 | static void | ||
833 | lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba) | ||
834 | { | ||
835 | struct lpfc_nodelist *ndlp; | ||
836 | |||
837 | spin_lock_irq(phba->host->host_lock); | ||
838 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) | ||
839 | if (ndlp->rport) | ||
840 | ndlp->rport->dev_loss_tmo = phba->cfg_devloss_tmo; | ||
841 | spin_unlock_irq(phba->host->host_lock); | ||
842 | } | ||
843 | |||
844 | static int | 885 | static int |
845 | lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) | 886 | lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) |
846 | { | 887 | { |
@@ -856,7 +897,6 @@ lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) | |||
856 | if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { | 897 | if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { |
857 | phba->cfg_nodev_tmo = val; | 898 | phba->cfg_nodev_tmo = val; |
858 | phba->cfg_devloss_tmo = val; | 899 | phba->cfg_devloss_tmo = val; |
859 | lpfc_update_rport_devloss_tmo(phba); | ||
860 | return 0; | 900 | return 0; |
861 | } | 901 | } |
862 | 902 | ||
@@ -892,7 +932,6 @@ lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val) | |||
892 | phba->cfg_nodev_tmo = val; | 932 | phba->cfg_nodev_tmo = val; |
893 | phba->cfg_devloss_tmo = val; | 933 | phba->cfg_devloss_tmo = val; |
894 | phba->dev_loss_tmo_changed = 1; | 934 | phba->dev_loss_tmo_changed = 1; |
895 | lpfc_update_rport_devloss_tmo(phba); | ||
896 | return 0; | 935 | return 0; |
897 | } | 936 | } |
898 | 937 | ||
@@ -1088,7 +1127,7 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255, | |||
1088 | LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); | 1127 | LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); |
1089 | 1128 | ||
1090 | 1129 | ||
1091 | struct class_device_attribute *lpfc_host_attrs[] = { | 1130 | struct class_device_attribute *lpfc_hba_attrs[] = { |
1092 | &class_device_attr_info, | 1131 | &class_device_attr_info, |
1093 | &class_device_attr_serialnum, | 1132 | &class_device_attr_serialnum, |
1094 | &class_device_attr_modeldesc, | 1133 | &class_device_attr_modeldesc, |
@@ -1136,9 +1175,11 @@ static ssize_t | |||
1136 | sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | 1175 | sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) |
1137 | { | 1176 | { |
1138 | size_t buf_off; | 1177 | size_t buf_off; |
1139 | struct Scsi_Host *host = class_to_shost(container_of(kobj, | 1178 | struct class_device *cdev = container_of(kobj, struct class_device, |
1140 | struct class_device, kobj)); | 1179 | kobj); |
1141 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 1180 | struct Scsi_Host *shost = class_to_shost(cdev); |
1181 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
1182 | struct lpfc_hba *phba = vport->phba; | ||
1142 | 1183 | ||
1143 | if ((off + count) > FF_REG_AREA_SIZE) | 1184 | if ((off + count) > FF_REG_AREA_SIZE) |
1144 | return -ERANGE; | 1185 | return -ERANGE; |
@@ -1148,18 +1189,16 @@ sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1148 | if (off % 4 || count % 4 || (unsigned long)buf % 4) | 1189 | if (off % 4 || count % 4 || (unsigned long)buf % 4) |
1149 | return -EINVAL; | 1190 | return -EINVAL; |
1150 | 1191 | ||
1151 | spin_lock_irq(phba->host->host_lock); | 1192 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) { |
1152 | |||
1153 | if (!(phba->fc_flag & FC_OFFLINE_MODE)) { | ||
1154 | spin_unlock_irq(phba->host->host_lock); | ||
1155 | return -EPERM; | 1193 | return -EPERM; |
1156 | } | 1194 | } |
1157 | 1195 | ||
1196 | spin_lock_irq(&phba->hbalock); | ||
1158 | for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) | 1197 | for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) |
1159 | writel(*((uint32_t *)(buf + buf_off)), | 1198 | writel(*((uint32_t *)(buf + buf_off)), |
1160 | phba->ctrl_regs_memmap_p + off + buf_off); | 1199 | phba->ctrl_regs_memmap_p + off + buf_off); |
1161 | 1200 | ||
1162 | spin_unlock_irq(phba->host->host_lock); | 1201 | spin_unlock_irq(&phba->hbalock); |
1163 | 1202 | ||
1164 | return count; | 1203 | return count; |
1165 | } | 1204 | } |
@@ -1169,9 +1208,11 @@ sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1169 | { | 1208 | { |
1170 | size_t buf_off; | 1209 | size_t buf_off; |
1171 | uint32_t * tmp_ptr; | 1210 | uint32_t * tmp_ptr; |
1172 | struct Scsi_Host *host = class_to_shost(container_of(kobj, | 1211 | struct class_device *cdev = container_of(kobj, struct class_device, |
1173 | struct class_device, kobj)); | 1212 | kobj); |
1174 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 1213 | struct Scsi_Host *shost = class_to_shost(cdev); |
1214 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
1215 | struct lpfc_hba *phba = vport->phba; | ||
1175 | 1216 | ||
1176 | if (off > FF_REG_AREA_SIZE) | 1217 | if (off > FF_REG_AREA_SIZE) |
1177 | return -ERANGE; | 1218 | return -ERANGE; |
@@ -1184,14 +1225,14 @@ sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1184 | if (off % 4 || count % 4 || (unsigned long)buf % 4) | 1225 | if (off % 4 || count % 4 || (unsigned long)buf % 4) |
1185 | return -EINVAL; | 1226 | return -EINVAL; |
1186 | 1227 | ||
1187 | spin_lock_irq(phba->host->host_lock); | 1228 | spin_lock_irq(&phba->hbalock); |
1188 | 1229 | ||
1189 | for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) { | 1230 | for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) { |
1190 | tmp_ptr = (uint32_t *)(buf + buf_off); | 1231 | tmp_ptr = (uint32_t *)(buf + buf_off); |
1191 | *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off); | 1232 | *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off); |
1192 | } | 1233 | } |
1193 | 1234 | ||
1194 | spin_unlock_irq(phba->host->host_lock); | 1235 | spin_unlock_irq(&phba->hbalock); |
1195 | 1236 | ||
1196 | return count; | 1237 | return count; |
1197 | } | 1238 | } |
@@ -1209,7 +1250,7 @@ static struct bin_attribute sysfs_ctlreg_attr = { | |||
1209 | 1250 | ||
1210 | 1251 | ||
1211 | static void | 1252 | static void |
1212 | sysfs_mbox_idle (struct lpfc_hba * phba) | 1253 | sysfs_mbox_idle(struct lpfc_hba *phba) |
1213 | { | 1254 | { |
1214 | phba->sysfs_mbox.state = SMBOX_IDLE; | 1255 | phba->sysfs_mbox.state = SMBOX_IDLE; |
1215 | phba->sysfs_mbox.offset = 0; | 1256 | phba->sysfs_mbox.offset = 0; |
@@ -1224,10 +1265,12 @@ sysfs_mbox_idle (struct lpfc_hba * phba) | |||
1224 | static ssize_t | 1265 | static ssize_t |
1225 | sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | 1266 | sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) |
1226 | { | 1267 | { |
1227 | struct Scsi_Host * host = | 1268 | struct class_device *cdev = container_of(kobj, struct class_device, |
1228 | class_to_shost(container_of(kobj, struct class_device, kobj)); | 1269 | kobj); |
1229 | struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata; | 1270 | struct Scsi_Host *shost = class_to_shost(cdev); |
1230 | struct lpfcMboxq * mbox = NULL; | 1271 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1272 | struct lpfc_hba *phba = vport->phba; | ||
1273 | struct lpfcMboxq *mbox = NULL; | ||
1231 | 1274 | ||
1232 | if ((count + off) > MAILBOX_CMD_SIZE) | 1275 | if ((count + off) > MAILBOX_CMD_SIZE) |
1233 | return -ERANGE; | 1276 | return -ERANGE; |
@@ -1245,7 +1288,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1245 | memset(mbox, 0, sizeof (LPFC_MBOXQ_t)); | 1288 | memset(mbox, 0, sizeof (LPFC_MBOXQ_t)); |
1246 | } | 1289 | } |
1247 | 1290 | ||
1248 | spin_lock_irq(host->host_lock); | 1291 | spin_lock_irq(&phba->hbalock); |
1249 | 1292 | ||
1250 | if (off == 0) { | 1293 | if (off == 0) { |
1251 | if (phba->sysfs_mbox.mbox) | 1294 | if (phba->sysfs_mbox.mbox) |
@@ -1258,7 +1301,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1258 | phba->sysfs_mbox.offset != off || | 1301 | phba->sysfs_mbox.offset != off || |
1259 | phba->sysfs_mbox.mbox == NULL ) { | 1302 | phba->sysfs_mbox.mbox == NULL ) { |
1260 | sysfs_mbox_idle(phba); | 1303 | sysfs_mbox_idle(phba); |
1261 | spin_unlock_irq(host->host_lock); | 1304 | spin_unlock_irq(&phba->hbalock); |
1262 | return -EAGAIN; | 1305 | return -EAGAIN; |
1263 | } | 1306 | } |
1264 | } | 1307 | } |
@@ -1268,7 +1311,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1268 | 1311 | ||
1269 | phba->sysfs_mbox.offset = off + count; | 1312 | phba->sysfs_mbox.offset = off + count; |
1270 | 1313 | ||
1271 | spin_unlock_irq(host->host_lock); | 1314 | spin_unlock_irq(&phba->hbalock); |
1272 | 1315 | ||
1273 | return count; | 1316 | return count; |
1274 | } | 1317 | } |
@@ -1276,10 +1319,11 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1276 | static ssize_t | 1319 | static ssize_t |
1277 | sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | 1320 | sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) |
1278 | { | 1321 | { |
1279 | struct Scsi_Host *host = | 1322 | struct class_device *cdev = container_of(kobj, struct class_device, |
1280 | class_to_shost(container_of(kobj, struct class_device, | 1323 | kobj); |
1281 | kobj)); | 1324 | struct Scsi_Host *shost = class_to_shost(cdev); |
1282 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 1325 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1326 | struct lpfc_hba *phba = vport->phba; | ||
1283 | int rc; | 1327 | int rc; |
1284 | 1328 | ||
1285 | if (off > MAILBOX_CMD_SIZE) | 1329 | if (off > MAILBOX_CMD_SIZE) |
@@ -1294,7 +1338,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1294 | if (off && count == 0) | 1338 | if (off && count == 0) |
1295 | return 0; | 1339 | return 0; |
1296 | 1340 | ||
1297 | spin_lock_irq(phba->host->host_lock); | 1341 | spin_lock_irq(&phba->hbalock); |
1298 | 1342 | ||
1299 | if (off == 0 && | 1343 | if (off == 0 && |
1300 | phba->sysfs_mbox.state == SMBOX_WRITING && | 1344 | phba->sysfs_mbox.state == SMBOX_WRITING && |
@@ -1317,12 +1361,12 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1317 | case MBX_SET_MASK: | 1361 | case MBX_SET_MASK: |
1318 | case MBX_SET_SLIM: | 1362 | case MBX_SET_SLIM: |
1319 | case MBX_SET_DEBUG: | 1363 | case MBX_SET_DEBUG: |
1320 | if (!(phba->fc_flag & FC_OFFLINE_MODE)) { | 1364 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) { |
1321 | printk(KERN_WARNING "mbox_read:Command 0x%x " | 1365 | printk(KERN_WARNING "mbox_read:Command 0x%x " |
1322 | "is illegal in on-line state\n", | 1366 | "is illegal in on-line state\n", |
1323 | phba->sysfs_mbox.mbox->mb.mbxCommand); | 1367 | phba->sysfs_mbox.mbox->mb.mbxCommand); |
1324 | sysfs_mbox_idle(phba); | 1368 | sysfs_mbox_idle(phba); |
1325 | spin_unlock_irq(phba->host->host_lock); | 1369 | spin_unlock_irq(&phba->hbalock); |
1326 | return -EPERM; | 1370 | return -EPERM; |
1327 | } | 1371 | } |
1328 | case MBX_LOAD_SM: | 1372 | case MBX_LOAD_SM: |
@@ -1352,38 +1396,38 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1352 | printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n", | 1396 | printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n", |
1353 | phba->sysfs_mbox.mbox->mb.mbxCommand); | 1397 | phba->sysfs_mbox.mbox->mb.mbxCommand); |
1354 | sysfs_mbox_idle(phba); | 1398 | sysfs_mbox_idle(phba); |
1355 | spin_unlock_irq(phba->host->host_lock); | 1399 | spin_unlock_irq(&phba->hbalock); |
1356 | return -EPERM; | 1400 | return -EPERM; |
1357 | default: | 1401 | default: |
1358 | printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n", | 1402 | printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n", |
1359 | phba->sysfs_mbox.mbox->mb.mbxCommand); | 1403 | phba->sysfs_mbox.mbox->mb.mbxCommand); |
1360 | sysfs_mbox_idle(phba); | 1404 | sysfs_mbox_idle(phba); |
1361 | spin_unlock_irq(phba->host->host_lock); | 1405 | spin_unlock_irq(&phba->hbalock); |
1362 | return -EPERM; | 1406 | return -EPERM; |
1363 | } | 1407 | } |
1364 | 1408 | ||
1365 | if (phba->fc_flag & FC_BLOCK_MGMT_IO) { | 1409 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { |
1366 | sysfs_mbox_idle(phba); | 1410 | sysfs_mbox_idle(phba); |
1367 | spin_unlock_irq(host->host_lock); | 1411 | spin_unlock_irq(&phba->hbalock); |
1368 | return -EAGAIN; | 1412 | return -EAGAIN; |
1369 | } | 1413 | } |
1370 | 1414 | ||
1371 | if ((phba->fc_flag & FC_OFFLINE_MODE) || | 1415 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
1372 | (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){ | 1416 | (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){ |
1373 | 1417 | ||
1374 | spin_unlock_irq(phba->host->host_lock); | 1418 | spin_unlock_irq(&phba->hbalock); |
1375 | rc = lpfc_sli_issue_mbox (phba, | 1419 | rc = lpfc_sli_issue_mbox (phba, |
1376 | phba->sysfs_mbox.mbox, | 1420 | phba->sysfs_mbox.mbox, |
1377 | MBX_POLL); | 1421 | MBX_POLL); |
1378 | spin_lock_irq(phba->host->host_lock); | 1422 | spin_lock_irq(&phba->hbalock); |
1379 | 1423 | ||
1380 | } else { | 1424 | } else { |
1381 | spin_unlock_irq(phba->host->host_lock); | 1425 | spin_unlock_irq(&phba->hbalock); |
1382 | rc = lpfc_sli_issue_mbox_wait (phba, | 1426 | rc = lpfc_sli_issue_mbox_wait (phba, |
1383 | phba->sysfs_mbox.mbox, | 1427 | phba->sysfs_mbox.mbox, |
1384 | lpfc_mbox_tmo_val(phba, | 1428 | lpfc_mbox_tmo_val(phba, |
1385 | phba->sysfs_mbox.mbox->mb.mbxCommand) * HZ); | 1429 | phba->sysfs_mbox.mbox->mb.mbxCommand) * HZ); |
1386 | spin_lock_irq(phba->host->host_lock); | 1430 | spin_lock_irq(&phba->hbalock); |
1387 | } | 1431 | } |
1388 | 1432 | ||
1389 | if (rc != MBX_SUCCESS) { | 1433 | if (rc != MBX_SUCCESS) { |
@@ -1393,7 +1437,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1393 | phba->sysfs_mbox.mbox = NULL; | 1437 | phba->sysfs_mbox.mbox = NULL; |
1394 | } | 1438 | } |
1395 | sysfs_mbox_idle(phba); | 1439 | sysfs_mbox_idle(phba); |
1396 | spin_unlock_irq(host->host_lock); | 1440 | spin_unlock_irq(&phba->hbalock); |
1397 | return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV; | 1441 | return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV; |
1398 | } | 1442 | } |
1399 | phba->sysfs_mbox.state = SMBOX_READING; | 1443 | phba->sysfs_mbox.state = SMBOX_READING; |
@@ -1402,7 +1446,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1402 | phba->sysfs_mbox.state != SMBOX_READING) { | 1446 | phba->sysfs_mbox.state != SMBOX_READING) { |
1403 | printk(KERN_WARNING "mbox_read: Bad State\n"); | 1447 | printk(KERN_WARNING "mbox_read: Bad State\n"); |
1404 | sysfs_mbox_idle(phba); | 1448 | sysfs_mbox_idle(phba); |
1405 | spin_unlock_irq(host->host_lock); | 1449 | spin_unlock_irq(&phba->hbalock); |
1406 | return -EAGAIN; | 1450 | return -EAGAIN; |
1407 | } | 1451 | } |
1408 | 1452 | ||
@@ -1413,7 +1457,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1413 | if (phba->sysfs_mbox.offset == MAILBOX_CMD_SIZE) | 1457 | if (phba->sysfs_mbox.offset == MAILBOX_CMD_SIZE) |
1414 | sysfs_mbox_idle(phba); | 1458 | sysfs_mbox_idle(phba); |
1415 | 1459 | ||
1416 | spin_unlock_irq(phba->host->host_lock); | 1460 | spin_unlock_irq(&phba->hbalock); |
1417 | 1461 | ||
1418 | return count; | 1462 | return count; |
1419 | } | 1463 | } |
@@ -1430,35 +1474,35 @@ static struct bin_attribute sysfs_mbox_attr = { | |||
1430 | }; | 1474 | }; |
1431 | 1475 | ||
1432 | int | 1476 | int |
1433 | lpfc_alloc_sysfs_attr(struct lpfc_hba *phba) | 1477 | lpfc_alloc_sysfs_attr(struct lpfc_vport *vport) |
1434 | { | 1478 | { |
1435 | struct Scsi_Host *host = phba->host; | 1479 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1436 | int error; | 1480 | int error; |
1437 | 1481 | ||
1438 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, | 1482 | error = sysfs_create_bin_file(&shost->shost_classdev.kobj, |
1439 | &sysfs_ctlreg_attr); | 1483 | &sysfs_ctlreg_attr); |
1440 | if (error) | 1484 | if (error) |
1441 | goto out; | 1485 | goto out; |
1442 | 1486 | ||
1443 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, | 1487 | error = sysfs_create_bin_file(&shost->shost_classdev.kobj, |
1444 | &sysfs_mbox_attr); | 1488 | &sysfs_mbox_attr); |
1445 | if (error) | 1489 | if (error) |
1446 | goto out_remove_ctlreg_attr; | 1490 | goto out_remove_ctlreg_attr; |
1447 | 1491 | ||
1448 | return 0; | 1492 | return 0; |
1449 | out_remove_ctlreg_attr: | 1493 | out_remove_ctlreg_attr: |
1450 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr); | 1494 | sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr); |
1451 | out: | 1495 | out: |
1452 | return error; | 1496 | return error; |
1453 | } | 1497 | } |
1454 | 1498 | ||
1455 | void | 1499 | void |
1456 | lpfc_free_sysfs_attr(struct lpfc_hba *phba) | 1500 | lpfc_free_sysfs_attr(struct lpfc_vport *vport) |
1457 | { | 1501 | { |
1458 | struct Scsi_Host *host = phba->host; | 1502 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1459 | 1503 | ||
1460 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_mbox_attr); | 1504 | sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_mbox_attr); |
1461 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr); | 1505 | sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr); |
1462 | } | 1506 | } |
1463 | 1507 | ||
1464 | 1508 | ||
@@ -1469,26 +1513,28 @@ lpfc_free_sysfs_attr(struct lpfc_hba *phba) | |||
1469 | static void | 1513 | static void |
1470 | lpfc_get_host_port_id(struct Scsi_Host *shost) | 1514 | lpfc_get_host_port_id(struct Scsi_Host *shost) |
1471 | { | 1515 | { |
1472 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; | 1516 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1517 | |||
1473 | /* note: fc_myDID already in cpu endianness */ | 1518 | /* note: fc_myDID already in cpu endianness */ |
1474 | fc_host_port_id(shost) = phba->fc_myDID; | 1519 | fc_host_port_id(shost) = vport->fc_myDID; |
1475 | } | 1520 | } |
1476 | 1521 | ||
1477 | static void | 1522 | static void |
1478 | lpfc_get_host_port_type(struct Scsi_Host *shost) | 1523 | lpfc_get_host_port_type(struct Scsi_Host *shost) |
1479 | { | 1524 | { |
1480 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; | 1525 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1526 | struct lpfc_hba *phba = vport->phba; | ||
1481 | 1527 | ||
1482 | spin_lock_irq(shost->host_lock); | 1528 | spin_lock_irq(shost->host_lock); |
1483 | 1529 | ||
1484 | if (phba->hba_state == LPFC_HBA_READY) { | 1530 | if (lpfc_is_link_up(phba)) { |
1485 | if (phba->fc_topology == TOPOLOGY_LOOP) { | 1531 | if (phba->fc_topology == TOPOLOGY_LOOP) { |
1486 | if (phba->fc_flag & FC_PUBLIC_LOOP) | 1532 | if (vport->fc_flag & FC_PUBLIC_LOOP) |
1487 | fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; | 1533 | fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; |
1488 | else | 1534 | else |
1489 | fc_host_port_type(shost) = FC_PORTTYPE_LPORT; | 1535 | fc_host_port_type(shost) = FC_PORTTYPE_LPORT; |
1490 | } else { | 1536 | } else { |
1491 | if (phba->fc_flag & FC_FABRIC) | 1537 | if (vport->fc_flag & FC_FABRIC) |
1492 | fc_host_port_type(shost) = FC_PORTTYPE_NPORT; | 1538 | fc_host_port_type(shost) = FC_PORTTYPE_NPORT; |
1493 | else | 1539 | else |
1494 | fc_host_port_type(shost) = FC_PORTTYPE_PTP; | 1540 | fc_host_port_type(shost) = FC_PORTTYPE_PTP; |
@@ -1502,31 +1548,21 @@ lpfc_get_host_port_type(struct Scsi_Host *shost) | |||
1502 | static void | 1548 | static void |
1503 | lpfc_get_host_port_state(struct Scsi_Host *shost) | 1549 | lpfc_get_host_port_state(struct Scsi_Host *shost) |
1504 | { | 1550 | { |
1505 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; | 1551 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1552 | struct lpfc_hba *phba = vport->phba; | ||
1506 | 1553 | ||
1507 | spin_lock_irq(shost->host_lock); | 1554 | spin_lock_irq(shost->host_lock); |
1508 | 1555 | ||
1509 | if (phba->fc_flag & FC_OFFLINE_MODE) | 1556 | if (vport->fc_flag & FC_OFFLINE_MODE) |
1510 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; | 1557 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; |
1511 | else { | 1558 | else { |
1512 | switch (phba->hba_state) { | 1559 | switch (phba->link_state) { |
1513 | case LPFC_STATE_UNKNOWN: | 1560 | case LPFC_LINK_UNKNOWN: |
1514 | case LPFC_WARM_START: | ||
1515 | case LPFC_INIT_START: | ||
1516 | case LPFC_INIT_MBX_CMDS: | ||
1517 | case LPFC_LINK_DOWN: | 1561 | case LPFC_LINK_DOWN: |
1518 | fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; | 1562 | fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; |
1519 | break; | 1563 | break; |
1520 | case LPFC_LINK_UP: | 1564 | case LPFC_LINK_UP: |
1521 | case LPFC_LOCAL_CFG_LINK: | ||
1522 | case LPFC_FLOGI: | ||
1523 | case LPFC_FABRIC_CFG_LINK: | ||
1524 | case LPFC_NS_REG: | ||
1525 | case LPFC_NS_QRY: | ||
1526 | case LPFC_BUILD_DISC_LIST: | ||
1527 | case LPFC_DISC_AUTH: | ||
1528 | case LPFC_CLEAR_LA: | 1565 | case LPFC_CLEAR_LA: |
1529 | case LPFC_HBA_READY: | ||
1530 | /* Links up, beyond this port_type reports state */ | 1566 | /* Links up, beyond this port_type reports state */ |
1531 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; | 1567 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; |
1532 | break; | 1568 | break; |
@@ -1545,11 +1581,12 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) | |||
1545 | static void | 1581 | static void |
1546 | lpfc_get_host_speed(struct Scsi_Host *shost) | 1582 | lpfc_get_host_speed(struct Scsi_Host *shost) |
1547 | { | 1583 | { |
1548 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; | 1584 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1585 | struct lpfc_hba *phba = vport->phba; | ||
1549 | 1586 | ||
1550 | spin_lock_irq(shost->host_lock); | 1587 | spin_lock_irq(shost->host_lock); |
1551 | 1588 | ||
1552 | if (phba->hba_state == LPFC_HBA_READY) { | 1589 | if (lpfc_is_link_up(phba)) { |
1553 | switch(phba->fc_linkspeed) { | 1590 | switch(phba->fc_linkspeed) { |
1554 | case LA_1GHZ_LINK: | 1591 | case LA_1GHZ_LINK: |
1555 | fc_host_speed(shost) = FC_PORTSPEED_1GBIT; | 1592 | fc_host_speed(shost) = FC_PORTSPEED_1GBIT; |
@@ -1575,39 +1612,31 @@ lpfc_get_host_speed(struct Scsi_Host *shost) | |||
1575 | static void | 1612 | static void |
1576 | lpfc_get_host_fabric_name (struct Scsi_Host *shost) | 1613 | lpfc_get_host_fabric_name (struct Scsi_Host *shost) |
1577 | { | 1614 | { |
1578 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; | 1615 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1616 | struct lpfc_hba *phba = vport->phba; | ||
1579 | u64 node_name; | 1617 | u64 node_name; |
1580 | 1618 | ||
1581 | spin_lock_irq(shost->host_lock); | 1619 | spin_lock_irq(shost->host_lock); |
1582 | 1620 | ||
1583 | if ((phba->fc_flag & FC_FABRIC) || | 1621 | if ((vport->fc_flag & FC_FABRIC) || |
1584 | ((phba->fc_topology == TOPOLOGY_LOOP) && | 1622 | ((phba->fc_topology == TOPOLOGY_LOOP) && |
1585 | (phba->fc_flag & FC_PUBLIC_LOOP))) | 1623 | (vport->fc_flag & FC_PUBLIC_LOOP))) |
1586 | node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn); | 1624 | node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn); |
1587 | else | 1625 | else |
1588 | /* fabric is local port if there is no F/FL_Port */ | 1626 | /* fabric is local port if there is no F/FL_Port */ |
1589 | node_name = wwn_to_u64(phba->fc_nodename.u.wwn); | 1627 | node_name = wwn_to_u64(vport->fc_nodename.u.wwn); |
1590 | 1628 | ||
1591 | spin_unlock_irq(shost->host_lock); | 1629 | spin_unlock_irq(shost->host_lock); |
1592 | 1630 | ||
1593 | fc_host_fabric_name(shost) = node_name; | 1631 | fc_host_fabric_name(shost) = node_name; |
1594 | } | 1632 | } |
1595 | 1633 | ||
1596 | static void | ||
1597 | lpfc_get_host_symbolic_name (struct Scsi_Host *shost) | ||
1598 | { | ||
1599 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; | ||
1600 | |||
1601 | spin_lock_irq(shost->host_lock); | ||
1602 | lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(shost)); | ||
1603 | spin_unlock_irq(shost->host_lock); | ||
1604 | } | ||
1605 | |||
1606 | static struct fc_host_statistics * | 1634 | static struct fc_host_statistics * |
1607 | lpfc_get_stats(struct Scsi_Host *shost) | 1635 | lpfc_get_stats(struct Scsi_Host *shost) |
1608 | { | 1636 | { |
1609 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; | 1637 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1610 | struct lpfc_sli *psli = &phba->sli; | 1638 | struct lpfc_hba *phba = vport->phba; |
1639 | struct lpfc_sli *psli = &phba->sli; | ||
1611 | struct fc_host_statistics *hs = &phba->link_stats; | 1640 | struct fc_host_statistics *hs = &phba->link_stats; |
1612 | struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets; | 1641 | struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets; |
1613 | LPFC_MBOXQ_t *pmboxq; | 1642 | LPFC_MBOXQ_t *pmboxq; |
@@ -1615,7 +1644,15 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1615 | unsigned long seconds; | 1644 | unsigned long seconds; |
1616 | int rc = 0; | 1645 | int rc = 0; |
1617 | 1646 | ||
1618 | if (phba->fc_flag & FC_BLOCK_MGMT_IO) | 1647 | /* prevent udev from issuing mailbox commands |
1648 | * until the port is configured. | ||
1649 | */ | ||
1650 | if (phba->link_state < LPFC_LINK_DOWN || | ||
1651 | !phba->mbox_mem_pool || | ||
1652 | (phba->sli.sli_flag & LPFC_SLI2_ACTIVE) == 0) | ||
1653 | return NULL; | ||
1654 | |||
1655 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) | ||
1619 | return NULL; | 1656 | return NULL; |
1620 | 1657 | ||
1621 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1658 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
@@ -1628,7 +1665,7 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1628 | pmb->mbxOwner = OWN_HOST; | 1665 | pmb->mbxOwner = OWN_HOST; |
1629 | pmboxq->context1 = NULL; | 1666 | pmboxq->context1 = NULL; |
1630 | 1667 | ||
1631 | if ((phba->fc_flag & FC_OFFLINE_MODE) || | 1668 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
1632 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | 1669 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) |
1633 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); | 1670 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); |
1634 | else | 1671 | else |
@@ -1654,7 +1691,7 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1654 | pmb->mbxOwner = OWN_HOST; | 1691 | pmb->mbxOwner = OWN_HOST; |
1655 | pmboxq->context1 = NULL; | 1692 | pmboxq->context1 = NULL; |
1656 | 1693 | ||
1657 | if ((phba->fc_flag & FC_OFFLINE_MODE) || | 1694 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
1658 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | 1695 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) |
1659 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); | 1696 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); |
1660 | else | 1697 | else |
@@ -1711,14 +1748,15 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1711 | static void | 1748 | static void |
1712 | lpfc_reset_stats(struct Scsi_Host *shost) | 1749 | lpfc_reset_stats(struct Scsi_Host *shost) |
1713 | { | 1750 | { |
1714 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; | 1751 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1715 | struct lpfc_sli *psli = &phba->sli; | 1752 | struct lpfc_hba *phba = vport->phba; |
1716 | struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets; | 1753 | struct lpfc_sli *psli = &phba->sli; |
1754 | struct lpfc_lnk_stat *lso = &psli->lnk_stat_offsets; | ||
1717 | LPFC_MBOXQ_t *pmboxq; | 1755 | LPFC_MBOXQ_t *pmboxq; |
1718 | MAILBOX_t *pmb; | 1756 | MAILBOX_t *pmb; |
1719 | int rc = 0; | 1757 | int rc = 0; |
1720 | 1758 | ||
1721 | if (phba->fc_flag & FC_BLOCK_MGMT_IO) | 1759 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) |
1722 | return; | 1760 | return; |
1723 | 1761 | ||
1724 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1762 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
@@ -1732,7 +1770,7 @@ lpfc_reset_stats(struct Scsi_Host *shost) | |||
1732 | pmb->un.varWords[0] = 0x1; /* reset request */ | 1770 | pmb->un.varWords[0] = 0x1; /* reset request */ |
1733 | pmboxq->context1 = NULL; | 1771 | pmboxq->context1 = NULL; |
1734 | 1772 | ||
1735 | if ((phba->fc_flag & FC_OFFLINE_MODE) || | 1773 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
1736 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | 1774 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) |
1737 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); | 1775 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); |
1738 | else | 1776 | else |
@@ -1751,7 +1789,7 @@ lpfc_reset_stats(struct Scsi_Host *shost) | |||
1751 | pmb->mbxOwner = OWN_HOST; | 1789 | pmb->mbxOwner = OWN_HOST; |
1752 | pmboxq->context1 = NULL; | 1790 | pmboxq->context1 = NULL; |
1753 | 1791 | ||
1754 | if ((phba->fc_flag & FC_OFFLINE_MODE) || | 1792 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
1755 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | 1793 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) |
1756 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); | 1794 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); |
1757 | else | 1795 | else |
@@ -1789,13 +1827,13 @@ lpfc_reset_stats(struct Scsi_Host *shost) | |||
1789 | static struct lpfc_nodelist * | 1827 | static struct lpfc_nodelist * |
1790 | lpfc_get_node_by_target(struct scsi_target *starget) | 1828 | lpfc_get_node_by_target(struct scsi_target *starget) |
1791 | { | 1829 | { |
1792 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 1830 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
1793 | struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; | 1831 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1794 | struct lpfc_nodelist *ndlp; | 1832 | struct lpfc_nodelist *ndlp; |
1795 | 1833 | ||
1796 | spin_lock_irq(shost->host_lock); | 1834 | spin_lock_irq(shost->host_lock); |
1797 | /* Search for this, mapped, target ID */ | 1835 | /* Search for this, mapped, target ID */ |
1798 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { | 1836 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
1799 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && | 1837 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && |
1800 | starget->id == ndlp->nlp_sid) { | 1838 | starget->id == ndlp->nlp_sid) { |
1801 | spin_unlock_irq(shost->host_lock); | 1839 | spin_unlock_irq(shost->host_lock); |
@@ -1885,9 +1923,6 @@ struct fc_function_template lpfc_transport_functions = { | |||
1885 | .get_host_fabric_name = lpfc_get_host_fabric_name, | 1923 | .get_host_fabric_name = lpfc_get_host_fabric_name, |
1886 | .show_host_fabric_name = 1, | 1924 | .show_host_fabric_name = 1, |
1887 | 1925 | ||
1888 | .get_host_symbolic_name = lpfc_get_host_symbolic_name, | ||
1889 | .show_host_symbolic_name = 1, | ||
1890 | |||
1891 | /* | 1926 | /* |
1892 | * The LPFC driver treats linkdown handling as target loss events | 1927 | * The LPFC driver treats linkdown handling as target loss events |
1893 | * so there are no sysfs handlers for link_down_tmo. | 1928 | * so there are no sysfs handlers for link_down_tmo. |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index b8c2a8862d8..0081cffd928 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -26,6 +26,7 @@ void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); | |||
26 | int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, | 26 | int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, |
27 | struct lpfc_dmabuf *mp); | 27 | struct lpfc_dmabuf *mp); |
28 | void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *); | 28 | void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *); |
29 | void lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport); | ||
29 | void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); | 30 | void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); |
30 | int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *); | 31 | int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *); |
31 | void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *); | 32 | void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *); |
@@ -36,7 +37,6 @@ void lpfc_unreg_login(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *); | |||
36 | void lpfc_unreg_did(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *); | 37 | void lpfc_unreg_did(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *); |
37 | void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); | 38 | void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); |
38 | 39 | ||
39 | |||
40 | int lpfc_linkdown(struct lpfc_hba *); | 40 | int lpfc_linkdown(struct lpfc_hba *); |
41 | void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); | 41 | void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); |
42 | 42 | ||
@@ -45,70 +45,70 @@ void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | |||
45 | void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 45 | void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
46 | void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 46 | void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
47 | void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 47 | void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
48 | void lpfc_dequeue_node(struct lpfc_hba *, struct lpfc_nodelist *); | 48 | void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *); |
49 | void lpfc_nlp_set_state(struct lpfc_hba *, struct lpfc_nodelist *, int); | 49 | void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int); |
50 | void lpfc_drop_node(struct lpfc_hba *, struct lpfc_nodelist *); | 50 | void lpfc_drop_node(struct lpfc_vport *, struct lpfc_nodelist *); |
51 | void lpfc_set_disctmo(struct lpfc_hba *); | 51 | void lpfc_set_disctmo(struct lpfc_vport *); |
52 | int lpfc_can_disctmo(struct lpfc_hba *); | 52 | int lpfc_can_disctmo(struct lpfc_vport *); |
53 | int lpfc_unreg_rpi(struct lpfc_hba *, struct lpfc_nodelist *); | 53 | int lpfc_unreg_rpi(struct lpfc_vport *, struct lpfc_nodelist *); |
54 | int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, | 54 | int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, |
55 | struct lpfc_iocbq *, struct lpfc_nodelist *); | 55 | struct lpfc_iocbq *, struct lpfc_nodelist *); |
56 | void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t); | 56 | void lpfc_nlp_init(struct lpfc_vport *, struct lpfc_nodelist *, uint32_t); |
57 | struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); | 57 | struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); |
58 | int lpfc_nlp_put(struct lpfc_nodelist *); | 58 | int lpfc_nlp_put(struct lpfc_nodelist *); |
59 | struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t); | 59 | struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_vport *, uint32_t); |
60 | void lpfc_disc_list_loopmap(struct lpfc_hba *); | 60 | void lpfc_disc_list_loopmap(struct lpfc_vport *); |
61 | void lpfc_disc_start(struct lpfc_hba *); | 61 | void lpfc_disc_start(struct lpfc_vport *); |
62 | void lpfc_disc_flush_list(struct lpfc_hba *); | 62 | void lpfc_disc_flush_list(struct lpfc_vport *); |
63 | void lpfc_disc_timeout(unsigned long); | 63 | void lpfc_disc_timeout(unsigned long); |
64 | 64 | ||
65 | struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi); | 65 | struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); |
66 | struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi); | 66 | struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); |
67 | 67 | ||
68 | int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); | 68 | int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); |
69 | int lpfc_do_work(void *); | 69 | int lpfc_do_work(void *); |
70 | int lpfc_disc_state_machine(struct lpfc_hba *, struct lpfc_nodelist *, void *, | 70 | int lpfc_disc_state_machine(struct lpfc_vport *, struct lpfc_nodelist *, void *, |
71 | uint32_t); | 71 | uint32_t); |
72 | 72 | ||
73 | int lpfc_check_sparm(struct lpfc_hba *, struct lpfc_nodelist *, | 73 | int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *, |
74 | struct serv_parm *, uint32_t); | 74 | struct serv_parm *, uint32_t); |
75 | int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp); | 75 | int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp); |
76 | int lpfc_els_abort_flogi(struct lpfc_hba *); | 76 | int lpfc_els_abort_flogi(struct lpfc_hba *); |
77 | int lpfc_initial_flogi(struct lpfc_hba *); | 77 | int lpfc_initial_flogi(struct lpfc_vport *); |
78 | int lpfc_issue_els_plogi(struct lpfc_hba *, uint32_t, uint8_t); | 78 | int lpfc_issue_els_plogi(struct lpfc_vport *, uint32_t, uint8_t); |
79 | int lpfc_issue_els_prli(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); | 79 | int lpfc_issue_els_prli(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); |
80 | int lpfc_issue_els_adisc(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); | 80 | int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); |
81 | int lpfc_issue_els_logo(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); | 81 | int lpfc_issue_els_logo(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); |
82 | int lpfc_issue_els_scr(struct lpfc_hba *, uint32_t, uint8_t); | 82 | int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t); |
83 | int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); | 83 | int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); |
84 | int lpfc_els_rsp_acc(struct lpfc_hba *, uint32_t, struct lpfc_iocbq *, | 84 | int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *, |
85 | struct lpfc_nodelist *, LPFC_MBOXQ_t *, uint8_t); | 85 | struct lpfc_nodelist *, LPFC_MBOXQ_t *, uint8_t); |
86 | int lpfc_els_rsp_reject(struct lpfc_hba *, uint32_t, struct lpfc_iocbq *, | 86 | int lpfc_els_rsp_reject(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *, |
87 | struct lpfc_nodelist *); | 87 | struct lpfc_nodelist *); |
88 | int lpfc_els_rsp_adisc_acc(struct lpfc_hba *, struct lpfc_iocbq *, | 88 | int lpfc_els_rsp_adisc_acc(struct lpfc_vport *, struct lpfc_iocbq *, |
89 | struct lpfc_nodelist *); | 89 | struct lpfc_nodelist *); |
90 | int lpfc_els_rsp_prli_acc(struct lpfc_hba *, struct lpfc_iocbq *, | 90 | int lpfc_els_rsp_prli_acc(struct lpfc_vport *, struct lpfc_iocbq *, |
91 | struct lpfc_nodelist *); | 91 | struct lpfc_nodelist *); |
92 | void lpfc_cancel_retry_delay_tmo(struct lpfc_hba *, struct lpfc_nodelist *); | 92 | void lpfc_cancel_retry_delay_tmo(struct lpfc_vport *, struct lpfc_nodelist *); |
93 | void lpfc_els_retry_delay(unsigned long); | 93 | void lpfc_els_retry_delay(unsigned long); |
94 | void lpfc_els_retry_delay_handler(struct lpfc_nodelist *); | 94 | void lpfc_els_retry_delay_handler(struct lpfc_nodelist *); |
95 | void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, | 95 | void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, |
96 | struct lpfc_iocbq *); | 96 | struct lpfc_iocbq *); |
97 | int lpfc_els_handle_rscn(struct lpfc_hba *); | 97 | int lpfc_els_handle_rscn(struct lpfc_vport *); |
98 | int lpfc_els_flush_rscn(struct lpfc_hba *); | 98 | int lpfc_els_flush_rscn(struct lpfc_vport *); |
99 | int lpfc_rscn_payload_check(struct lpfc_hba *, uint32_t); | 99 | int lpfc_rscn_payload_check(struct lpfc_vport *, uint32_t); |
100 | void lpfc_els_flush_cmd(struct lpfc_hba *); | 100 | void lpfc_els_flush_cmd(struct lpfc_vport *); |
101 | int lpfc_els_disc_adisc(struct lpfc_hba *); | 101 | int lpfc_els_disc_adisc(struct lpfc_vport *); |
102 | int lpfc_els_disc_plogi(struct lpfc_hba *); | 102 | int lpfc_els_disc_plogi(struct lpfc_vport *); |
103 | void lpfc_els_timeout(unsigned long); | 103 | void lpfc_els_timeout(unsigned long); |
104 | void lpfc_els_timeout_handler(struct lpfc_hba *); | 104 | void lpfc_els_timeout_handler(struct lpfc_vport *); |
105 | 105 | ||
106 | void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, | 106 | void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, |
107 | struct lpfc_iocbq *); | 107 | struct lpfc_iocbq *); |
108 | int lpfc_ns_cmd(struct lpfc_hba *, struct lpfc_nodelist *, int); | 108 | int lpfc_ns_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); |
109 | int lpfc_fdmi_cmd(struct lpfc_hba *, struct lpfc_nodelist *, int); | 109 | int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); |
110 | void lpfc_fdmi_tmo(unsigned long); | 110 | void lpfc_fdmi_tmo(unsigned long); |
111 | void lpfc_fdmi_tmo_handler(struct lpfc_hba *); | 111 | void lpfc_fdmi_timeout_handler(struct lpfc_vport *vport); |
112 | 112 | ||
113 | int lpfc_config_port_prep(struct lpfc_hba *); | 113 | int lpfc_config_port_prep(struct lpfc_hba *); |
114 | int lpfc_config_port_post(struct lpfc_hba *); | 114 | int lpfc_config_port_post(struct lpfc_hba *); |
@@ -146,6 +146,7 @@ void lpfc_poll_start_timer(struct lpfc_hba * phba); | |||
146 | void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba); | 146 | void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba); |
147 | struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); | 147 | struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); |
148 | void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); | 148 | void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); |
149 | void __lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); | ||
149 | uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); | 150 | uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); |
150 | 151 | ||
151 | void lpfc_reset_barrier(struct lpfc_hba * phba); | 152 | void lpfc_reset_barrier(struct lpfc_hba * phba); |
@@ -154,6 +155,7 @@ int lpfc_sli_brdkill(struct lpfc_hba *); | |||
154 | int lpfc_sli_brdreset(struct lpfc_hba *); | 155 | int lpfc_sli_brdreset(struct lpfc_hba *); |
155 | int lpfc_sli_brdrestart(struct lpfc_hba *); | 156 | int lpfc_sli_brdrestart(struct lpfc_hba *); |
156 | int lpfc_sli_hba_setup(struct lpfc_hba *); | 157 | int lpfc_sli_hba_setup(struct lpfc_hba *); |
158 | int lpfc_sli_host_down(struct lpfc_vport *); | ||
157 | int lpfc_sli_hba_down(struct lpfc_hba *); | 159 | int lpfc_sli_hba_down(struct lpfc_hba *); |
158 | int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); | 160 | int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); |
159 | int lpfc_sli_handle_mb_event(struct lpfc_hba *); | 161 | int lpfc_sli_handle_mb_event(struct lpfc_hba *); |
@@ -164,7 +166,7 @@ void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); | |||
164 | int lpfc_sli_issue_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, | 166 | int lpfc_sli_issue_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, |
165 | struct lpfc_iocbq *, uint32_t); | 167 | struct lpfc_iocbq *, uint32_t); |
166 | void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t); | 168 | void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t); |
167 | int lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *); | 169 | void lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *); |
168 | int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *, | 170 | int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *, |
169 | struct lpfc_dmabuf *); | 171 | struct lpfc_dmabuf *); |
170 | struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *, | 172 | struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *, |
@@ -173,15 +175,16 @@ struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *, | |||
173 | int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *, | 175 | int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *, |
174 | struct lpfc_iocbq *); | 176 | struct lpfc_iocbq *); |
175 | int lpfc_sli_sum_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, | 177 | int lpfc_sli_sum_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, |
176 | uint64_t, lpfc_ctx_cmd); | 178 | uint64_t, lpfc_ctx_cmd); |
177 | int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, | 179 | int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, |
178 | uint64_t, uint32_t, lpfc_ctx_cmd); | 180 | uint64_t, uint32_t, lpfc_ctx_cmd); |
179 | 181 | ||
180 | void lpfc_mbox_timeout(unsigned long); | 182 | void lpfc_mbox_timeout(unsigned long); |
181 | void lpfc_mbox_timeout_handler(struct lpfc_hba *); | 183 | void lpfc_mbox_timeout_handler(struct lpfc_hba *); |
182 | 184 | ||
183 | struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba *, uint32_t); | 185 | struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t); |
184 | struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_hba *, struct lpfc_name *); | 186 | struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *, |
187 | struct lpfc_name *); | ||
185 | 188 | ||
186 | int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | 189 | int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, |
187 | uint32_t timeout); | 190 | uint32_t timeout); |
@@ -196,6 +199,7 @@ void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, | |||
196 | struct lpfc_iocbq * rspiocb); | 199 | struct lpfc_iocbq * rspiocb); |
197 | 200 | ||
198 | void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *); | 201 | void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *); |
202 | void __lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t); | ||
199 | void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t); | 203 | void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t); |
200 | 204 | ||
201 | /* Function prototypes. */ | 205 | /* Function prototypes. */ |
@@ -204,17 +208,18 @@ void lpfc_scan_start(struct Scsi_Host *); | |||
204 | int lpfc_scan_finished(struct Scsi_Host *, unsigned long); | 208 | int lpfc_scan_finished(struct Scsi_Host *, unsigned long); |
205 | 209 | ||
206 | void lpfc_get_cfgparam(struct lpfc_hba *); | 210 | void lpfc_get_cfgparam(struct lpfc_hba *); |
207 | int lpfc_alloc_sysfs_attr(struct lpfc_hba *); | 211 | int lpfc_alloc_sysfs_attr(struct lpfc_vport *); |
208 | void lpfc_free_sysfs_attr(struct lpfc_hba *); | 212 | void lpfc_free_sysfs_attr(struct lpfc_vport *); |
209 | extern struct class_device_attribute *lpfc_host_attrs[]; | 213 | extern struct class_device_attribute *lpfc_hba_attrs[]; |
210 | extern struct scsi_host_template lpfc_template; | 214 | extern struct scsi_host_template lpfc_template; |
211 | extern struct fc_function_template lpfc_transport_functions; | 215 | extern struct fc_function_template lpfc_transport_functions; |
212 | 216 | ||
213 | void lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp); | 217 | void lpfc_get_hba_sym_node_name(struct lpfc_hba *phba, uint8_t *symbp); |
214 | void lpfc_terminate_rport_io(struct fc_rport *); | 218 | void lpfc_terminate_rport_io(struct fc_rport *); |
215 | void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport); | 219 | void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport); |
216 | 220 | ||
221 | struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int); | ||
222 | void lpfc_post_hba_setup_vport_init(struct lpfc_vport *); | ||
223 | void destroy_port(struct lpfc_vport *); | ||
224 | |||
217 | #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) | 225 | #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) |
218 | #define HBA_EVENT_RSCN 5 | ||
219 | #define HBA_EVENT_LINK_UP 2 | ||
220 | #define HBA_EVENT_LINK_DOWN 3 | ||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 34a9e3bb261..dc25a53524c 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -59,13 +59,13 @@ static char *lpfc_release_version = LPFC_DRIVER_VERSION; | |||
59 | * lpfc_ct_unsol_event | 59 | * lpfc_ct_unsol_event |
60 | */ | 60 | */ |
61 | void | 61 | void |
62 | lpfc_ct_unsol_event(struct lpfc_hba * phba, | 62 | lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
63 | struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocbq) | 63 | struct lpfc_iocbq *piocbq) |
64 | { | 64 | { |
65 | 65 | ||
66 | struct lpfc_iocbq *next_piocbq; | 66 | struct lpfc_iocbq *next_piocbq; |
67 | struct lpfc_dmabuf *pmbuf = NULL; | 67 | struct lpfc_dmabuf *pmbuf = NULL; |
68 | struct lpfc_dmabuf *matp, *next_matp; | 68 | struct lpfc_dmabuf *matp = NULL, *next_matp; |
69 | uint32_t ctx = 0, size = 0, cnt = 0; | 69 | uint32_t ctx = 0, size = 0, cnt = 0; |
70 | IOCB_t *icmd = &piocbq->iocb; | 70 | IOCB_t *icmd = &piocbq->iocb; |
71 | IOCB_t *save_icmd = icmd; | 71 | IOCB_t *save_icmd = icmd; |
@@ -145,7 +145,7 @@ ct_unsol_event_exit_piocbq: | |||
145 | } | 145 | } |
146 | 146 | ||
147 | static void | 147 | static void |
148 | lpfc_free_ct_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mlist) | 148 | lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist) |
149 | { | 149 | { |
150 | struct lpfc_dmabuf *mlast, *next_mlast; | 150 | struct lpfc_dmabuf *mlast, *next_mlast; |
151 | 151 | ||
@@ -160,7 +160,7 @@ lpfc_free_ct_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mlist) | |||
160 | } | 160 | } |
161 | 161 | ||
162 | static struct lpfc_dmabuf * | 162 | static struct lpfc_dmabuf * |
163 | lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl, | 163 | lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl, |
164 | uint32_t size, int *entries) | 164 | uint32_t size, int *entries) |
165 | { | 165 | { |
166 | struct lpfc_dmabuf *mlist = NULL; | 166 | struct lpfc_dmabuf *mlist = NULL; |
@@ -216,23 +216,21 @@ lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl, | |||
216 | } | 216 | } |
217 | 217 | ||
218 | static int | 218 | static int |
219 | lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, | 219 | lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, |
220 | struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp, | 220 | struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp, |
221 | void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, | 221 | void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, |
222 | struct lpfc_iocbq *), | 222 | struct lpfc_iocbq *), |
223 | struct lpfc_nodelist *ndlp, uint32_t usr_flg, uint32_t num_entry, | 223 | struct lpfc_nodelist *ndlp, uint32_t usr_flg, uint32_t num_entry, |
224 | uint32_t tmo) | 224 | uint32_t tmo) |
225 | { | 225 | { |
226 | 226 | struct lpfc_hba *phba = vport->phba; | |
227 | struct lpfc_sli *psli = &phba->sli; | 227 | struct lpfc_sli *psli = &phba->sli; |
228 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; | 228 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; |
229 | IOCB_t *icmd; | 229 | IOCB_t *icmd; |
230 | struct lpfc_iocbq *geniocb; | 230 | struct lpfc_iocbq *geniocb; |
231 | 231 | ||
232 | /* Allocate buffer for command iocb */ | 232 | /* Allocate buffer for command iocb */ |
233 | spin_lock_irq(phba->host->host_lock); | ||
234 | geniocb = lpfc_sli_get_iocbq(phba); | 233 | geniocb = lpfc_sli_get_iocbq(phba); |
235 | spin_unlock_irq(phba->host->host_lock); | ||
236 | 234 | ||
237 | if (geniocb == NULL) | 235 | if (geniocb == NULL) |
238 | return 1; | 236 | return 1; |
@@ -276,27 +274,26 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, | |||
276 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 274 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
277 | "%d:0119 Issue GEN REQ IOCB for NPORT x%x " | 275 | "%d:0119 Issue GEN REQ IOCB for NPORT x%x " |
278 | "Data: x%x x%x\n", phba->brd_no, icmd->un.ulpWord[5], | 276 | "Data: x%x x%x\n", phba->brd_no, icmd->un.ulpWord[5], |
279 | icmd->ulpIoTag, phba->hba_state); | 277 | icmd->ulpIoTag, vport->port_state); |
280 | geniocb->iocb_cmpl = cmpl; | 278 | geniocb->iocb_cmpl = cmpl; |
281 | geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT; | 279 | geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT; |
282 | spin_lock_irq(phba->host->host_lock); | 280 | geniocb->vport = vport; |
283 | if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) { | 281 | if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) { |
284 | lpfc_sli_release_iocbq(phba, geniocb); | 282 | lpfc_sli_release_iocbq(phba, geniocb); |
285 | spin_unlock_irq(phba->host->host_lock); | ||
286 | return 1; | 283 | return 1; |
287 | } | 284 | } |
288 | spin_unlock_irq(phba->host->host_lock); | ||
289 | 285 | ||
290 | return 0; | 286 | return 0; |
291 | } | 287 | } |
292 | 288 | ||
293 | static int | 289 | static int |
294 | lpfc_ct_cmd(struct lpfc_hba *phba, struct lpfc_dmabuf *inmp, | 290 | lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp, |
295 | struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp, | 291 | struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp, |
296 | void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, | 292 | void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, |
297 | struct lpfc_iocbq *), | 293 | struct lpfc_iocbq *), |
298 | uint32_t rsp_size) | 294 | uint32_t rsp_size) |
299 | { | 295 | { |
296 | struct lpfc_hba *phba = vport->phba; | ||
300 | struct ulp_bde64 *bpl = (struct ulp_bde64 *) bmp->virt; | 297 | struct ulp_bde64 *bpl = (struct ulp_bde64 *) bmp->virt; |
301 | struct lpfc_dmabuf *outmp; | 298 | struct lpfc_dmabuf *outmp; |
302 | int cnt = 0, status; | 299 | int cnt = 0, status; |
@@ -310,7 +307,7 @@ lpfc_ct_cmd(struct lpfc_hba *phba, struct lpfc_dmabuf *inmp, | |||
310 | if (!outmp) | 307 | if (!outmp) |
311 | return -ENOMEM; | 308 | return -ENOMEM; |
312 | 309 | ||
313 | status = lpfc_gen_req(phba, bmp, inmp, outmp, cmpl, ndlp, 0, | 310 | status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0, |
314 | cnt+1, 0); | 311 | cnt+1, 0); |
315 | if (status) { | 312 | if (status) { |
316 | lpfc_free_ct_rsp(phba, outmp); | 313 | lpfc_free_ct_rsp(phba, outmp); |
@@ -320,19 +317,20 @@ lpfc_ct_cmd(struct lpfc_hba *phba, struct lpfc_dmabuf *inmp, | |||
320 | } | 317 | } |
321 | 318 | ||
322 | static int | 319 | static int |
323 | lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) | 320 | lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) |
324 | { | 321 | { |
322 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
323 | struct lpfc_hba *phba = vport->phba; | ||
325 | struct lpfc_sli_ct_request *Response = | 324 | struct lpfc_sli_ct_request *Response = |
326 | (struct lpfc_sli_ct_request *) mp->virt; | 325 | (struct lpfc_sli_ct_request *) mp->virt; |
327 | struct lpfc_nodelist *ndlp = NULL; | 326 | struct lpfc_nodelist *ndlp = NULL; |
328 | struct lpfc_dmabuf *mlast, *next_mp; | 327 | struct lpfc_dmabuf *mlast, *next_mp; |
329 | uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; | 328 | uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; |
330 | uint32_t Did; | 329 | uint32_t Did, CTentry; |
331 | uint32_t CTentry; | ||
332 | int Cnt; | 330 | int Cnt; |
333 | struct list_head head; | 331 | struct list_head head; |
334 | 332 | ||
335 | lpfc_set_disctmo(phba); | 333 | lpfc_set_disctmo(vport); |
336 | 334 | ||
337 | 335 | ||
338 | list_add_tail(&head, &mp->list); | 336 | list_add_tail(&head, &mp->list); |
@@ -350,39 +348,31 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) | |||
350 | 348 | ||
351 | /* Loop through entire NameServer list of DIDs */ | 349 | /* Loop through entire NameServer list of DIDs */ |
352 | while (Cnt >= sizeof (uint32_t)) { | 350 | while (Cnt >= sizeof (uint32_t)) { |
353 | |||
354 | /* Get next DID from NameServer List */ | 351 | /* Get next DID from NameServer List */ |
355 | CTentry = *ctptr++; | 352 | CTentry = *ctptr++; |
356 | Did = ((be32_to_cpu(CTentry)) & Mask_DID); | 353 | Did = ((be32_to_cpu(CTentry)) & Mask_DID); |
357 | |||
358 | ndlp = NULL; | 354 | ndlp = NULL; |
359 | if (Did != phba->fc_myDID) { | 355 | /* Check for rscn processing or not */ |
360 | /* Check for rscn processing or not */ | 356 | if (Did != vport->fc_myDID) |
361 | ndlp = lpfc_setup_disc_node(phba, Did); | 357 | ndlp = lpfc_setup_disc_node(vport, Did); |
362 | } | ||
363 | /* Mark all node table entries that are in the | ||
364 | Nameserver */ | ||
365 | if (ndlp) { | 358 | if (ndlp) { |
366 | /* NameServer Rsp */ | ||
367 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 359 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
368 | "%d:0238 Process x%x NameServer" | 360 | "%d:0238 Process x%x NameServer" |
369 | " Rsp Data: x%x x%x x%x\n", | 361 | " Rsp Data: x%x x%x x%x\n", |
370 | phba->brd_no, | 362 | phba->brd_no, |
371 | Did, ndlp->nlp_flag, | 363 | Did, ndlp->nlp_flag, |
372 | phba->fc_flag, | 364 | vport->fc_flag, |
373 | phba->fc_rscn_id_cnt); | 365 | vport->fc_rscn_id_cnt); |
374 | } else { | 366 | } else { |
375 | /* NameServer Rsp */ | ||
376 | lpfc_printf_log(phba, | 367 | lpfc_printf_log(phba, |
377 | KERN_INFO, | 368 | KERN_INFO, |
378 | LOG_DISCOVERY, | 369 | LOG_DISCOVERY, |
379 | "%d:0239 Skip x%x NameServer " | 370 | "%d:0239 Skip x%x NameServer " |
380 | "Rsp Data: x%x x%x x%x\n", | 371 | "Rsp Data: x%x x%x x%x\n", |
381 | phba->brd_no, | 372 | phba->brd_no, |
382 | Did, Size, phba->fc_flag, | 373 | Did, Size, vport->fc_flag, |
383 | phba->fc_rscn_id_cnt); | 374 | vport->fc_rscn_id_cnt); |
384 | } | 375 | } |
385 | |||
386 | if (CTentry & (be32_to_cpu(SLI_CT_LAST_ENTRY))) | 376 | if (CTentry & (be32_to_cpu(SLI_CT_LAST_ENTRY))) |
387 | goto nsout1; | 377 | goto nsout1; |
388 | Cnt -= sizeof (uint32_t); | 378 | Cnt -= sizeof (uint32_t); |
@@ -395,15 +385,15 @@ nsout1: | |||
395 | list_del(&head); | 385 | list_del(&head); |
396 | 386 | ||
397 | /* | 387 | /* |
398 | * The driver has cycled through all Nports in the RSCN payload. | 388 | * The driver has cycled through all Nports in the RSCN payload. |
399 | * Complete the handling by cleaning up and marking the | 389 | * Complete the handling by cleaning up and marking the |
400 | * current driver state. | 390 | * current driver state. |
401 | */ | 391 | */ |
402 | if (phba->hba_state == LPFC_HBA_READY) { | 392 | if (vport->port_state == LPFC_VPORT_READY) { |
403 | lpfc_els_flush_rscn(phba); | 393 | lpfc_els_flush_rscn(vport); |
404 | spin_lock_irq(phba->host->host_lock); | 394 | spin_lock_irq(shost->host_lock); |
405 | phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */ | 395 | vport->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */ |
406 | spin_unlock_irq(phba->host->host_lock); | 396 | spin_unlock_irq(shost->host_lock); |
407 | } | 397 | } |
408 | return 0; | 398 | return 0; |
409 | } | 399 | } |
@@ -412,18 +402,18 @@ nsout1: | |||
412 | 402 | ||
413 | 403 | ||
414 | static void | 404 | static void |
415 | lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 405 | lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
416 | struct lpfc_iocbq * rspiocb) | 406 | struct lpfc_iocbq *rspiocb) |
417 | { | 407 | { |
408 | struct lpfc_vport *vport = cmdiocb->vport; | ||
418 | IOCB_t *irsp; | 409 | IOCB_t *irsp; |
419 | struct lpfc_sli *psli; | ||
420 | struct lpfc_dmabuf *bmp; | 410 | struct lpfc_dmabuf *bmp; |
421 | struct lpfc_dmabuf *inp; | 411 | struct lpfc_dmabuf *inp; |
422 | struct lpfc_dmabuf *outp; | 412 | struct lpfc_dmabuf *outp; |
423 | struct lpfc_nodelist *ndlp; | 413 | struct lpfc_nodelist *ndlp; |
424 | struct lpfc_sli_ct_request *CTrsp; | 414 | struct lpfc_sli_ct_request *CTrsp; |
415 | int rc; | ||
425 | 416 | ||
426 | psli = &phba->sli; | ||
427 | /* we pass cmdiocb to state machine which needs rspiocb as well */ | 417 | /* we pass cmdiocb to state machine which needs rspiocb as well */ |
428 | cmdiocb->context_un.rsp_iocb = rspiocb; | 418 | cmdiocb->context_un.rsp_iocb = rspiocb; |
429 | 419 | ||
@@ -435,22 +425,20 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
435 | if (irsp->ulpStatus) { | 425 | if (irsp->ulpStatus) { |
436 | if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && | 426 | if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && |
437 | ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) || | 427 | ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) || |
438 | (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))) { | 428 | (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))) |
439 | goto out; | 429 | goto out; |
440 | } | ||
441 | 430 | ||
442 | /* Check for retry */ | 431 | /* Check for retry */ |
443 | if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) { | 432 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { |
444 | phba->fc_ns_retry++; | 433 | vport->fc_ns_retry++; |
445 | /* CT command is being retried */ | 434 | /* CT command is being retried */ |
446 | ndlp = lpfc_findnode_did(phba, NameServer_DID); | 435 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
447 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 436 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { |
448 | if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == | 437 | rc = lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT); |
449 | 0) { | 438 | if (rc == 0) |
450 | goto out; | 439 | goto out; |
451 | } | 440 | } |
452 | } | 441 | } |
453 | } | ||
454 | } else { | 442 | } else { |
455 | /* Good status, continue checking */ | 443 | /* Good status, continue checking */ |
456 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | 444 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; |
@@ -460,8 +448,8 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
460 | "%d:0208 NameServer Rsp " | 448 | "%d:0208 NameServer Rsp " |
461 | "Data: x%x\n", | 449 | "Data: x%x\n", |
462 | phba->brd_no, | 450 | phba->brd_no, |
463 | phba->fc_flag); | 451 | vport->fc_flag); |
464 | lpfc_ns_rsp(phba, outp, | 452 | lpfc_ns_rsp(vport, outp, |
465 | (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); | 453 | (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); |
466 | } else if (CTrsp->CommandResponse.bits.CmdRsp == | 454 | } else if (CTrsp->CommandResponse.bits.CmdRsp == |
467 | be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { | 455 | be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { |
@@ -473,7 +461,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
473 | CTrsp->CommandResponse.bits.CmdRsp, | 461 | CTrsp->CommandResponse.bits.CmdRsp, |
474 | (uint32_t) CTrsp->ReasonCode, | 462 | (uint32_t) CTrsp->ReasonCode, |
475 | (uint32_t) CTrsp->Explanation, | 463 | (uint32_t) CTrsp->Explanation, |
476 | phba->fc_flag); | 464 | vport->fc_flag); |
477 | } else { | 465 | } else { |
478 | /* NameServer Rsp Error */ | 466 | /* NameServer Rsp Error */ |
479 | lpfc_printf_log(phba, | 467 | lpfc_printf_log(phba, |
@@ -485,35 +473,31 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
485 | CTrsp->CommandResponse.bits.CmdRsp, | 473 | CTrsp->CommandResponse.bits.CmdRsp, |
486 | (uint32_t) CTrsp->ReasonCode, | 474 | (uint32_t) CTrsp->ReasonCode, |
487 | (uint32_t) CTrsp->Explanation, | 475 | (uint32_t) CTrsp->Explanation, |
488 | phba->fc_flag); | 476 | vport->fc_flag); |
489 | } | 477 | } |
490 | } | 478 | } |
491 | /* Link up / RSCN discovery */ | 479 | /* Link up / RSCN discovery */ |
492 | lpfc_disc_start(phba); | 480 | lpfc_disc_start(vport); |
493 | out: | 481 | out: |
494 | lpfc_free_ct_rsp(phba, outp); | 482 | lpfc_free_ct_rsp(phba, outp); |
495 | lpfc_mbuf_free(phba, inp->virt, inp->phys); | 483 | lpfc_mbuf_free(phba, inp->virt, inp->phys); |
496 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | 484 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); |
497 | kfree(inp); | 485 | kfree(inp); |
498 | kfree(bmp); | 486 | kfree(bmp); |
499 | spin_lock_irq(phba->host->host_lock); | ||
500 | lpfc_sli_release_iocbq(phba, cmdiocb); | 487 | lpfc_sli_release_iocbq(phba, cmdiocb); |
501 | spin_unlock_irq(phba->host->host_lock); | ||
502 | return; | 488 | return; |
503 | } | 489 | } |
504 | 490 | ||
505 | static void | 491 | static void |
506 | lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 492 | lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
507 | struct lpfc_iocbq * rspiocb) | 493 | struct lpfc_iocbq *rspiocb) |
508 | { | 494 | { |
509 | struct lpfc_sli *psli; | ||
510 | struct lpfc_dmabuf *bmp; | 495 | struct lpfc_dmabuf *bmp; |
511 | struct lpfc_dmabuf *inp; | 496 | struct lpfc_dmabuf *inp; |
512 | struct lpfc_dmabuf *outp; | 497 | struct lpfc_dmabuf *outp; |
513 | IOCB_t *irsp; | 498 | IOCB_t *irsp; |
514 | struct lpfc_sli_ct_request *CTrsp; | 499 | struct lpfc_sli_ct_request *CTrsp; |
515 | 500 | ||
516 | psli = &phba->sli; | ||
517 | /* we pass cmdiocb to state machine which needs rspiocb as well */ | 501 | /* we pass cmdiocb to state machine which needs rspiocb as well */ |
518 | cmdiocb->context_un.rsp_iocb = rspiocb; | 502 | cmdiocb->context_un.rsp_iocb = rspiocb; |
519 | 503 | ||
@@ -527,31 +511,31 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
527 | /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */ | 511 | /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */ |
528 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 512 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
529 | "%d:0209 RFT request completes ulpStatus x%x " | 513 | "%d:0209 RFT request completes ulpStatus x%x " |
530 | "CmdRsp x%x\n", phba->brd_no, irsp->ulpStatus, | 514 | "CmdRsp x%x, Context x%x, Tag x%x\n", |
531 | CTrsp->CommandResponse.bits.CmdRsp); | 515 | phba->brd_no, irsp->ulpStatus, |
516 | CTrsp->CommandResponse.bits.CmdRsp, | ||
517 | cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag); | ||
532 | 518 | ||
533 | lpfc_free_ct_rsp(phba, outp); | 519 | lpfc_free_ct_rsp(phba, outp); |
534 | lpfc_mbuf_free(phba, inp->virt, inp->phys); | 520 | lpfc_mbuf_free(phba, inp->virt, inp->phys); |
535 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | 521 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); |
536 | kfree(inp); | 522 | kfree(inp); |
537 | kfree(bmp); | 523 | kfree(bmp); |
538 | spin_lock_irq(phba->host->host_lock); | ||
539 | lpfc_sli_release_iocbq(phba, cmdiocb); | 524 | lpfc_sli_release_iocbq(phba, cmdiocb); |
540 | spin_unlock_irq(phba->host->host_lock); | ||
541 | return; | 525 | return; |
542 | } | 526 | } |
543 | 527 | ||
544 | static void | 528 | static void |
545 | lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 529 | lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
546 | struct lpfc_iocbq * rspiocb) | 530 | struct lpfc_iocbq *rspiocb) |
547 | { | 531 | { |
548 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 532 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); |
549 | return; | 533 | return; |
550 | } | 534 | } |
551 | 535 | ||
552 | static void | 536 | static void |
553 | lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 537 | lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
554 | struct lpfc_iocbq * rspiocb) | 538 | struct lpfc_iocbq *rspiocb) |
555 | { | 539 | { |
556 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 540 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); |
557 | return; | 541 | return; |
@@ -566,7 +550,7 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
566 | } | 550 | } |
567 | 551 | ||
568 | void | 552 | void |
569 | lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp) | 553 | lpfc_get_hba_sym_node_name(struct lpfc_hba *phba, uint8_t *symbp) |
570 | { | 554 | { |
571 | char fwrev[16]; | 555 | char fwrev[16]; |
572 | 556 | ||
@@ -585,8 +569,9 @@ lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp) | |||
585 | * LI_CTNS_RFT_ID | 569 | * LI_CTNS_RFT_ID |
586 | */ | 570 | */ |
587 | int | 571 | int |
588 | lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | 572 | lpfc_ns_cmd(struct lpfc_vport *vport, struct lpfc_nodelist * ndlp, int cmdcode) |
589 | { | 573 | { |
574 | struct lpfc_hba *phba = vport->phba; | ||
590 | struct lpfc_dmabuf *mp, *bmp; | 575 | struct lpfc_dmabuf *mp, *bmp; |
591 | struct lpfc_sli_ct_request *CtReq; | 576 | struct lpfc_sli_ct_request *CtReq; |
592 | struct ulp_bde64 *bpl; | 577 | struct ulp_bde64 *bpl; |
@@ -620,8 +605,8 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
620 | KERN_INFO, | 605 | KERN_INFO, |
621 | LOG_DISCOVERY, | 606 | LOG_DISCOVERY, |
622 | "%d:0236 NameServer Req Data: x%x x%x x%x\n", | 607 | "%d:0236 NameServer Req Data: x%x x%x x%x\n", |
623 | phba->brd_no, cmdcode, phba->fc_flag, | 608 | phba->brd_no, cmdcode, vport->fc_flag, |
624 | phba->fc_rscn_id_cnt); | 609 | vport->fc_rscn_id_cnt); |
625 | 610 | ||
626 | bpl = (struct ulp_bde64 *) bmp->virt; | 611 | bpl = (struct ulp_bde64 *) bmp->virt; |
627 | memset(bpl, 0, sizeof(struct ulp_bde64)); | 612 | memset(bpl, 0, sizeof(struct ulp_bde64)); |
@@ -654,9 +639,9 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
654 | CtReq->CommandResponse.bits.CmdRsp = | 639 | CtReq->CommandResponse.bits.CmdRsp = |
655 | be16_to_cpu(SLI_CTNS_GID_FT); | 640 | be16_to_cpu(SLI_CTNS_GID_FT); |
656 | CtReq->un.gid.Fc4Type = SLI_CTPT_FCP; | 641 | CtReq->un.gid.Fc4Type = SLI_CTPT_FCP; |
657 | if (phba->hba_state < LPFC_HBA_READY) | 642 | if (vport->port_state < LPFC_VPORT_READY) |
658 | phba->hba_state = LPFC_NS_QRY; | 643 | vport->port_state = LPFC_NS_QRY; |
659 | lpfc_set_disctmo(phba); | 644 | lpfc_set_disctmo(vport); |
660 | cmpl = lpfc_cmpl_ct_cmd_gid_ft; | 645 | cmpl = lpfc_cmpl_ct_cmd_gid_ft; |
661 | rsp_size = FC_MAX_NS_RSP; | 646 | rsp_size = FC_MAX_NS_RSP; |
662 | break; | 647 | break; |
@@ -664,7 +649,7 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
664 | case SLI_CTNS_RFT_ID: | 649 | case SLI_CTNS_RFT_ID: |
665 | CtReq->CommandResponse.bits.CmdRsp = | 650 | CtReq->CommandResponse.bits.CmdRsp = |
666 | be16_to_cpu(SLI_CTNS_RFT_ID); | 651 | be16_to_cpu(SLI_CTNS_RFT_ID); |
667 | CtReq->un.rft.PortId = be32_to_cpu(phba->fc_myDID); | 652 | CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID); |
668 | CtReq->un.rft.fcpReg = 1; | 653 | CtReq->un.rft.fcpReg = 1; |
669 | cmpl = lpfc_cmpl_ct_cmd_rft_id; | 654 | cmpl = lpfc_cmpl_ct_cmd_rft_id; |
670 | break; | 655 | break; |
@@ -672,7 +657,7 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
672 | case SLI_CTNS_RFF_ID: | 657 | case SLI_CTNS_RFF_ID: |
673 | CtReq->CommandResponse.bits.CmdRsp = | 658 | CtReq->CommandResponse.bits.CmdRsp = |
674 | be16_to_cpu(SLI_CTNS_RFF_ID); | 659 | be16_to_cpu(SLI_CTNS_RFF_ID); |
675 | CtReq->un.rff.PortId = be32_to_cpu(phba->fc_myDID); | 660 | CtReq->un.rff.PortId = be32_to_cpu(vport->fc_myDID); |
676 | CtReq->un.rff.feature_res = 0; | 661 | CtReq->un.rff.feature_res = 0; |
677 | CtReq->un.rff.feature_tgt = 0; | 662 | CtReq->un.rff.feature_tgt = 0; |
678 | CtReq->un.rff.type_code = FC_FCP_DATA; | 663 | CtReq->un.rff.type_code = FC_FCP_DATA; |
@@ -683,8 +668,8 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
683 | case SLI_CTNS_RNN_ID: | 668 | case SLI_CTNS_RNN_ID: |
684 | CtReq->CommandResponse.bits.CmdRsp = | 669 | CtReq->CommandResponse.bits.CmdRsp = |
685 | be16_to_cpu(SLI_CTNS_RNN_ID); | 670 | be16_to_cpu(SLI_CTNS_RNN_ID); |
686 | CtReq->un.rnn.PortId = be32_to_cpu(phba->fc_myDID); | 671 | CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID); |
687 | memcpy(CtReq->un.rnn.wwnn, &phba->fc_nodename, | 672 | memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, |
688 | sizeof (struct lpfc_name)); | 673 | sizeof (struct lpfc_name)); |
689 | cmpl = lpfc_cmpl_ct_cmd_rnn_id; | 674 | cmpl = lpfc_cmpl_ct_cmd_rnn_id; |
690 | break; | 675 | break; |
@@ -692,7 +677,7 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
692 | case SLI_CTNS_RSNN_NN: | 677 | case SLI_CTNS_RSNN_NN: |
693 | CtReq->CommandResponse.bits.CmdRsp = | 678 | CtReq->CommandResponse.bits.CmdRsp = |
694 | be16_to_cpu(SLI_CTNS_RSNN_NN); | 679 | be16_to_cpu(SLI_CTNS_RSNN_NN); |
695 | memcpy(CtReq->un.rsnn.wwnn, &phba->fc_nodename, | 680 | memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, |
696 | sizeof (struct lpfc_name)); | 681 | sizeof (struct lpfc_name)); |
697 | lpfc_get_hba_sym_node_name(phba, CtReq->un.rsnn.symbname); | 682 | lpfc_get_hba_sym_node_name(phba, CtReq->un.rsnn.symbname); |
698 | CtReq->un.rsnn.len = strlen(CtReq->un.rsnn.symbname); | 683 | CtReq->un.rsnn.len = strlen(CtReq->un.rsnn.symbname); |
@@ -700,7 +685,7 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
700 | break; | 685 | break; |
701 | } | 686 | } |
702 | 687 | ||
703 | if (!lpfc_ct_cmd(phba, mp, bmp, ndlp, cmpl, rsp_size)) | 688 | if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size)) |
704 | /* On success, The cmpl function will free the buffers */ | 689 | /* On success, The cmpl function will free the buffers */ |
705 | return 0; | 690 | return 0; |
706 | 691 | ||
@@ -716,8 +701,8 @@ ns_cmd_exit: | |||
716 | } | 701 | } |
717 | 702 | ||
718 | static void | 703 | static void |
719 | lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba, | 704 | lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
720 | struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) | 705 | struct lpfc_iocbq * rspiocb) |
721 | { | 706 | { |
722 | struct lpfc_dmabuf *bmp = cmdiocb->context3; | 707 | struct lpfc_dmabuf *bmp = cmdiocb->context3; |
723 | struct lpfc_dmabuf *inp = cmdiocb->context1; | 708 | struct lpfc_dmabuf *inp = cmdiocb->context1; |
@@ -727,8 +712,9 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba, | |||
727 | struct lpfc_nodelist *ndlp; | 712 | struct lpfc_nodelist *ndlp; |
728 | uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; | 713 | uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; |
729 | uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp; | 714 | uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp; |
715 | struct lpfc_vport *vport = cmdiocb->vport; | ||
730 | 716 | ||
731 | ndlp = lpfc_findnode_did(phba, FDMI_DID); | 717 | ndlp = lpfc_findnode_did(vport, FDMI_DID); |
732 | if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { | 718 | if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { |
733 | /* FDMI rsp failed */ | 719 | /* FDMI rsp failed */ |
734 | lpfc_printf_log(phba, | 720 | lpfc_printf_log(phba, |
@@ -741,18 +727,18 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba, | |||
741 | 727 | ||
742 | switch (be16_to_cpu(fdmi_cmd)) { | 728 | switch (be16_to_cpu(fdmi_cmd)) { |
743 | case SLI_MGMT_RHBA: | 729 | case SLI_MGMT_RHBA: |
744 | lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_RPA); | 730 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA); |
745 | break; | 731 | break; |
746 | 732 | ||
747 | case SLI_MGMT_RPA: | 733 | case SLI_MGMT_RPA: |
748 | break; | 734 | break; |
749 | 735 | ||
750 | case SLI_MGMT_DHBA: | 736 | case SLI_MGMT_DHBA: |
751 | lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DPRT); | 737 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT); |
752 | break; | 738 | break; |
753 | 739 | ||
754 | case SLI_MGMT_DPRT: | 740 | case SLI_MGMT_DPRT: |
755 | lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_RHBA); | 741 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA); |
756 | break; | 742 | break; |
757 | } | 743 | } |
758 | 744 | ||
@@ -761,14 +747,14 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba, | |||
761 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | 747 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); |
762 | kfree(inp); | 748 | kfree(inp); |
763 | kfree(bmp); | 749 | kfree(bmp); |
764 | spin_lock_irq(phba->host->host_lock); | ||
765 | lpfc_sli_release_iocbq(phba, cmdiocb); | 750 | lpfc_sli_release_iocbq(phba, cmdiocb); |
766 | spin_unlock_irq(phba->host->host_lock); | ||
767 | return; | 751 | return; |
768 | } | 752 | } |
753 | |||
769 | int | 754 | int |
770 | lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | 755 | lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) |
771 | { | 756 | { |
757 | struct lpfc_hba *phba = vport->phba; | ||
772 | struct lpfc_dmabuf *mp, *bmp; | 758 | struct lpfc_dmabuf *mp, *bmp; |
773 | struct lpfc_sli_ct_request *CtReq; | 759 | struct lpfc_sli_ct_request *CtReq; |
774 | struct ulp_bde64 *bpl; | 760 | struct ulp_bde64 *bpl; |
@@ -810,7 +796,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
810 | LOG_DISCOVERY, | 796 | LOG_DISCOVERY, |
811 | "%d:0218 FDMI Request Data: x%x x%x x%x\n", | 797 | "%d:0218 FDMI Request Data: x%x x%x x%x\n", |
812 | phba->brd_no, | 798 | phba->brd_no, |
813 | phba->fc_flag, phba->hba_state, cmdcode); | 799 | vport->fc_flag, vport->port_state, cmdcode); |
814 | 800 | ||
815 | CtReq = (struct lpfc_sli_ct_request *) mp->virt; | 801 | CtReq = (struct lpfc_sli_ct_request *) mp->virt; |
816 | 802 | ||
@@ -833,11 +819,11 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
833 | be16_to_cpu(SLI_MGMT_RHBA); | 819 | be16_to_cpu(SLI_MGMT_RHBA); |
834 | CtReq->CommandResponse.bits.Size = 0; | 820 | CtReq->CommandResponse.bits.Size = 0; |
835 | rh = (REG_HBA *) & CtReq->un.PortID; | 821 | rh = (REG_HBA *) & CtReq->un.PortID; |
836 | memcpy(&rh->hi.PortName, &phba->fc_sparam.portName, | 822 | memcpy(&rh->hi.PortName, &vport->fc_sparam.portName, |
837 | sizeof (struct lpfc_name)); | 823 | sizeof (struct lpfc_name)); |
838 | /* One entry (port) per adapter */ | 824 | /* One entry (port) per adapter */ |
839 | rh->rpl.EntryCnt = be32_to_cpu(1); | 825 | rh->rpl.EntryCnt = be32_to_cpu(1); |
840 | memcpy(&rh->rpl.pe, &phba->fc_sparam.portName, | 826 | memcpy(&rh->rpl.pe, &vport->fc_sparam.portName, |
841 | sizeof (struct lpfc_name)); | 827 | sizeof (struct lpfc_name)); |
842 | 828 | ||
843 | /* point to the HBA attribute block */ | 829 | /* point to the HBA attribute block */ |
@@ -853,7 +839,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
853 | ae->ad.bits.AttrType = be16_to_cpu(NODE_NAME); | 839 | ae->ad.bits.AttrType = be16_to_cpu(NODE_NAME); |
854 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES | 840 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES |
855 | + sizeof (struct lpfc_name)); | 841 | + sizeof (struct lpfc_name)); |
856 | memcpy(&ae->un.NodeName, &phba->fc_sparam.nodeName, | 842 | memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName, |
857 | sizeof (struct lpfc_name)); | 843 | sizeof (struct lpfc_name)); |
858 | ab->EntryCnt++; | 844 | ab->EntryCnt++; |
859 | size += FOURBYTES + sizeof (struct lpfc_name); | 845 | size += FOURBYTES + sizeof (struct lpfc_name); |
@@ -991,7 +977,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
991 | pab = (REG_PORT_ATTRIBUTE *) & CtReq->un.PortID; | 977 | pab = (REG_PORT_ATTRIBUTE *) & CtReq->un.PortID; |
992 | size = sizeof (struct lpfc_name) + FOURBYTES; | 978 | size = sizeof (struct lpfc_name) + FOURBYTES; |
993 | memcpy((uint8_t *) & pab->PortName, | 979 | memcpy((uint8_t *) & pab->PortName, |
994 | (uint8_t *) & phba->fc_sparam.portName, | 980 | (uint8_t *) & vport->fc_sparam.portName, |
995 | sizeof (struct lpfc_name)); | 981 | sizeof (struct lpfc_name)); |
996 | pab->ab.EntryCnt = 0; | 982 | pab->ab.EntryCnt = 0; |
997 | 983 | ||
@@ -1053,7 +1039,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
1053 | ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); | 1039 | ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); |
1054 | ae->ad.bits.AttrType = be16_to_cpu(MAX_FRAME_SIZE); | 1040 | ae->ad.bits.AttrType = be16_to_cpu(MAX_FRAME_SIZE); |
1055 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); | 1041 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); |
1056 | hsp = (struct serv_parm *) & phba->fc_sparam; | 1042 | hsp = (struct serv_parm *) & vport->fc_sparam; |
1057 | ae->un.MaxFrameSize = | 1043 | ae->un.MaxFrameSize = |
1058 | (((uint32_t) hsp->cmn. | 1044 | (((uint32_t) hsp->cmn. |
1059 | bbRcvSizeMsb) << 8) | (uint32_t) hsp->cmn. | 1045 | bbRcvSizeMsb) << 8) | (uint32_t) hsp->cmn. |
@@ -1097,7 +1083,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
1097 | CtReq->CommandResponse.bits.Size = 0; | 1083 | CtReq->CommandResponse.bits.Size = 0; |
1098 | pe = (PORT_ENTRY *) & CtReq->un.PortID; | 1084 | pe = (PORT_ENTRY *) & CtReq->un.PortID; |
1099 | memcpy((uint8_t *) & pe->PortName, | 1085 | memcpy((uint8_t *) & pe->PortName, |
1100 | (uint8_t *) & phba->fc_sparam.portName, | 1086 | (uint8_t *) & vport->fc_sparam.portName, |
1101 | sizeof (struct lpfc_name)); | 1087 | sizeof (struct lpfc_name)); |
1102 | size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name); | 1088 | size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name); |
1103 | break; | 1089 | break; |
@@ -1107,7 +1093,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
1107 | CtReq->CommandResponse.bits.Size = 0; | 1093 | CtReq->CommandResponse.bits.Size = 0; |
1108 | pe = (PORT_ENTRY *) & CtReq->un.PortID; | 1094 | pe = (PORT_ENTRY *) & CtReq->un.PortID; |
1109 | memcpy((uint8_t *) & pe->PortName, | 1095 | memcpy((uint8_t *) & pe->PortName, |
1110 | (uint8_t *) & phba->fc_sparam.portName, | 1096 | (uint8_t *) & vport->fc_sparam.portName, |
1111 | sizeof (struct lpfc_name)); | 1097 | sizeof (struct lpfc_name)); |
1112 | size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name); | 1098 | size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name); |
1113 | break; | 1099 | break; |
@@ -1122,7 +1108,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
1122 | 1108 | ||
1123 | cmpl = lpfc_cmpl_ct_cmd_fdmi; | 1109 | cmpl = lpfc_cmpl_ct_cmd_fdmi; |
1124 | 1110 | ||
1125 | if (!lpfc_ct_cmd(phba, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP)) | 1111 | if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP)) |
1126 | return 0; | 1112 | return 0; |
1127 | 1113 | ||
1128 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | 1114 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); |
@@ -1146,37 +1132,36 @@ fdmi_cmd_exit: | |||
1146 | void | 1132 | void |
1147 | lpfc_fdmi_tmo(unsigned long ptr) | 1133 | lpfc_fdmi_tmo(unsigned long ptr) |
1148 | { | 1134 | { |
1149 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; | 1135 | struct lpfc_vport *vport = (struct lpfc_vport *)ptr; |
1136 | struct lpfc_hba *phba = vport->phba; | ||
1150 | unsigned long iflag; | 1137 | unsigned long iflag; |
1151 | 1138 | ||
1152 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1139 | spin_lock_irqsave(&vport->work_port_lock, iflag); |
1153 | if (!(phba->work_hba_events & WORKER_FDMI_TMO)) { | 1140 | if (!(vport->work_port_events & WORKER_FDMI_TMO)) { |
1154 | phba->work_hba_events |= WORKER_FDMI_TMO; | 1141 | vport->work_port_events |= WORKER_FDMI_TMO; |
1155 | if (phba->work_wait) | 1142 | if (phba->work_wait) |
1156 | wake_up(phba->work_wait); | 1143 | wake_up(phba->work_wait); |
1157 | } | 1144 | } |
1158 | spin_unlock_irqrestore(phba->host->host_lock,iflag); | 1145 | spin_unlock_irqrestore(&vport->work_port_lock, iflag); |
1159 | } | 1146 | } |
1160 | 1147 | ||
1161 | void | 1148 | void |
1162 | lpfc_fdmi_tmo_handler(struct lpfc_hba *phba) | 1149 | lpfc_fdmi_timeout_handler(struct lpfc_vport *vport) |
1163 | { | 1150 | { |
1164 | struct lpfc_nodelist *ndlp; | 1151 | struct lpfc_nodelist *ndlp; |
1165 | 1152 | ||
1166 | ndlp = lpfc_findnode_did(phba, FDMI_DID); | 1153 | ndlp = lpfc_findnode_did(vport, FDMI_DID); |
1167 | if (ndlp) { | 1154 | if (ndlp) { |
1168 | if (init_utsname()->nodename[0] != '\0') { | 1155 | if (init_utsname()->nodename[0] != '\0') |
1169 | lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA); | 1156 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); |
1170 | } else { | 1157 | else |
1171 | mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); | 1158 | mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); |
1172 | } | ||
1173 | } | 1159 | } |
1174 | return; | 1160 | return; |
1175 | } | 1161 | } |
1176 | 1162 | ||
1177 | |||
1178 | void | 1163 | void |
1179 | lpfc_decode_firmware_rev(struct lpfc_hba * phba, char *fwrevision, int flag) | 1164 | lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag) |
1180 | { | 1165 | { |
1181 | struct lpfc_sli *psli = &phba->sli; | 1166 | struct lpfc_sli *psli = &phba->sli; |
1182 | lpfc_vpd_t *vp = &phba->vpd; | 1167 | lpfc_vpd_t *vp = &phba->vpd; |
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 498059f3f7f..20bace56c8f 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h | |||
@@ -49,8 +49,8 @@ struct lpfc_work_evt { | |||
49 | 49 | ||
50 | struct lpfc_nodelist { | 50 | struct lpfc_nodelist { |
51 | struct list_head nlp_listp; | 51 | struct list_head nlp_listp; |
52 | struct lpfc_name nlp_portname; /* port name */ | 52 | struct lpfc_name nlp_portname; |
53 | struct lpfc_name nlp_nodename; /* node name */ | 53 | struct lpfc_name nlp_nodename; |
54 | uint32_t nlp_flag; /* entry flags */ | 54 | uint32_t nlp_flag; /* entry flags */ |
55 | uint32_t nlp_DID; /* FC D_ID of entry */ | 55 | uint32_t nlp_DID; /* FC D_ID of entry */ |
56 | uint32_t nlp_last_elscmd; /* Last ELS cmd sent */ | 56 | uint32_t nlp_last_elscmd; /* Last ELS cmd sent */ |
@@ -75,7 +75,7 @@ struct lpfc_nodelist { | |||
75 | struct timer_list nlp_delayfunc; /* Used for delayed ELS cmds */ | 75 | struct timer_list nlp_delayfunc; /* Used for delayed ELS cmds */ |
76 | struct fc_rport *rport; /* Corresponding FC transport | 76 | struct fc_rport *rport; /* Corresponding FC transport |
77 | port structure */ | 77 | port structure */ |
78 | struct lpfc_hba *nlp_phba; | 78 | struct lpfc_vport *vport; |
79 | struct lpfc_work_evt els_retry_evt; | 79 | struct lpfc_work_evt els_retry_evt; |
80 | unsigned long last_ramp_up_time; /* jiffy of last ramp up */ | 80 | unsigned long last_ramp_up_time; /* jiffy of last ramp up */ |
81 | unsigned long last_q_full_time; /* jiffy of last queue full */ | 81 | unsigned long last_q_full_time; /* jiffy of last queue full */ |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 638b3cd677b..0af33bead30 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -41,23 +41,20 @@ static int lpfc_els_retry(struct lpfc_hba *, struct lpfc_iocbq *, | |||
41 | static int lpfc_max_els_tries = 3; | 41 | static int lpfc_max_els_tries = 3; |
42 | 42 | ||
43 | static int | 43 | static int |
44 | lpfc_els_chk_latt(struct lpfc_hba * phba) | 44 | lpfc_els_chk_latt(struct lpfc_vport *vport) |
45 | { | 45 | { |
46 | struct lpfc_sli *psli; | 46 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
47 | struct lpfc_hba *phba = vport->phba; | ||
47 | LPFC_MBOXQ_t *mbox; | 48 | LPFC_MBOXQ_t *mbox; |
48 | uint32_t ha_copy; | 49 | uint32_t ha_copy; |
49 | int rc; | 50 | int rc; |
50 | 51 | ||
51 | psli = &phba->sli; | 52 | if (vport->port_state >= LPFC_VPORT_READY || |
52 | 53 | phba->link_state == LPFC_LINK_DOWN) | |
53 | if ((phba->hba_state >= LPFC_HBA_READY) || | ||
54 | (phba->hba_state == LPFC_LINK_DOWN)) | ||
55 | return 0; | 54 | return 0; |
56 | 55 | ||
57 | /* Read the HBA Host Attention Register */ | 56 | /* Read the HBA Host Attention Register */ |
58 | spin_lock_irq(phba->host->host_lock); | ||
59 | ha_copy = readl(phba->HAregaddr); | 57 | ha_copy = readl(phba->HAregaddr); |
60 | spin_unlock_irq(phba->host->host_lock); | ||
61 | 58 | ||
62 | if (!(ha_copy & HA_LATT)) | 59 | if (!(ha_copy & HA_LATT)) |
63 | return 0; | 60 | return 0; |
@@ -66,7 +63,7 @@ lpfc_els_chk_latt(struct lpfc_hba * phba) | |||
66 | lpfc_printf_log(phba, KERN_WARNING, LOG_DISCOVERY, | 63 | lpfc_printf_log(phba, KERN_WARNING, LOG_DISCOVERY, |
67 | "%d:0237 Pending Link Event during " | 64 | "%d:0237 Pending Link Event during " |
68 | "Discovery: State x%x\n", | 65 | "Discovery: State x%x\n", |
69 | phba->brd_no, phba->hba_state); | 66 | phba->brd_no, phba->pport->port_state); |
70 | 67 | ||
71 | /* CLEAR_LA should re-enable link attention events and | 68 | /* CLEAR_LA should re-enable link attention events and |
72 | * we should then imediately take a LATT event. The | 69 | * we should then imediately take a LATT event. The |
@@ -74,20 +71,23 @@ lpfc_els_chk_latt(struct lpfc_hba * phba) | |||
74 | * will cleanup any left over in-progress discovery | 71 | * will cleanup any left over in-progress discovery |
75 | * events. | 72 | * events. |
76 | */ | 73 | */ |
77 | spin_lock_irq(phba->host->host_lock); | 74 | spin_lock_irq(shost->host_lock); |
78 | phba->fc_flag |= FC_ABORT_DISCOVERY; | 75 | vport->fc_flag |= FC_ABORT_DISCOVERY; |
79 | spin_unlock_irq(phba->host->host_lock); | 76 | spin_unlock_irq(shost->host_lock); |
80 | 77 | ||
81 | if (phba->hba_state != LPFC_CLEAR_LA) { | 78 | if (phba->link_state != LPFC_CLEAR_LA) { |
82 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { | 79 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { |
83 | phba->hba_state = LPFC_CLEAR_LA; | 80 | phba->link_state = LPFC_CLEAR_LA; |
84 | lpfc_clear_la(phba, mbox); | 81 | lpfc_clear_la(phba, mbox); |
85 | mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 82 | mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
86 | rc = lpfc_sli_issue_mbox (phba, mbox, | 83 | mbox->vport = vport; |
87 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 84 | printk(KERN_ERR "%s (%d): do clear_la\n", |
85 | __FUNCTION__, __LINE__); | ||
86 | rc = lpfc_sli_issue_mbox(phba, mbox, | ||
87 | (MBX_NOWAIT | MBX_STOP_IOCB)); | ||
88 | if (rc == MBX_NOT_FINISHED) { | 88 | if (rc == MBX_NOT_FINISHED) { |
89 | mempool_free(mbox, phba->mbox_mem_pool); | 89 | mempool_free(mbox, phba->mbox_mem_pool); |
90 | phba->hba_state = LPFC_HBA_ERROR; | 90 | phba->link_state = LPFC_HBA_ERROR; |
91 | } | 91 | } |
92 | } | 92 | } |
93 | } | 93 | } |
@@ -97,25 +97,23 @@ lpfc_els_chk_latt(struct lpfc_hba * phba) | |||
97 | } | 97 | } |
98 | 98 | ||
99 | static struct lpfc_iocbq * | 99 | static struct lpfc_iocbq * |
100 | lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | 100 | lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, |
101 | uint16_t cmdSize, uint8_t retry, struct lpfc_nodelist * ndlp, | 101 | uint16_t cmdSize, uint8_t retry, |
102 | uint32_t did, uint32_t elscmd) | 102 | struct lpfc_nodelist *ndlp, uint32_t did, |
103 | uint32_t elscmd) | ||
103 | { | 104 | { |
104 | struct lpfc_sli_ring *pring; | 105 | struct lpfc_hba *phba = vport->phba; |
105 | struct lpfc_iocbq *elsiocb; | 106 | struct lpfc_iocbq *elsiocb; |
106 | struct lpfc_dmabuf *pcmd, *prsp, *pbuflist; | 107 | struct lpfc_dmabuf *pcmd, *prsp, *pbuflist; |
107 | struct ulp_bde64 *bpl; | 108 | struct ulp_bde64 *bpl; |
108 | IOCB_t *icmd; | 109 | IOCB_t *icmd; |
109 | 110 | ||
110 | pring = &phba->sli.ring[LPFC_ELS_RING]; | ||
111 | 111 | ||
112 | if (phba->hba_state < LPFC_LINK_UP) | 112 | if (!lpfc_is_link_up(phba)) |
113 | return NULL; | 113 | return NULL; |
114 | 114 | ||
115 | /* Allocate buffer for command iocb */ | 115 | /* Allocate buffer for command iocb */ |
116 | spin_lock_irq(phba->host->host_lock); | ||
117 | elsiocb = lpfc_sli_get_iocbq(phba); | 116 | elsiocb = lpfc_sli_get_iocbq(phba); |
118 | spin_unlock_irq(phba->host->host_lock); | ||
119 | 117 | ||
120 | if (elsiocb == NULL) | 118 | if (elsiocb == NULL) |
121 | return NULL; | 119 | return NULL; |
@@ -128,9 +126,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | |||
128 | MEM_PRI, &(pcmd->phys))) == 0)) { | 126 | MEM_PRI, &(pcmd->phys))) == 0)) { |
129 | kfree(pcmd); | 127 | kfree(pcmd); |
130 | 128 | ||
131 | spin_lock_irq(phba->host->host_lock); | ||
132 | lpfc_sli_release_iocbq(phba, elsiocb); | 129 | lpfc_sli_release_iocbq(phba, elsiocb); |
133 | spin_unlock_irq(phba->host->host_lock); | ||
134 | return NULL; | 130 | return NULL; |
135 | } | 131 | } |
136 | 132 | ||
@@ -146,9 +142,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | |||
146 | kfree(prsp); | 142 | kfree(prsp); |
147 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); | 143 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); |
148 | kfree(pcmd); | 144 | kfree(pcmd); |
149 | spin_lock_irq(phba->host->host_lock); | ||
150 | lpfc_sli_release_iocbq(phba, elsiocb); | 145 | lpfc_sli_release_iocbq(phba, elsiocb); |
151 | spin_unlock_irq(phba->host->host_lock); | ||
152 | return NULL; | 146 | return NULL; |
153 | } | 147 | } |
154 | INIT_LIST_HEAD(&prsp->list); | 148 | INIT_LIST_HEAD(&prsp->list); |
@@ -162,9 +156,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | |||
162 | pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, | 156 | pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, |
163 | &pbuflist->phys); | 157 | &pbuflist->phys); |
164 | if (pbuflist == 0 || pbuflist->virt == 0) { | 158 | if (pbuflist == 0 || pbuflist->virt == 0) { |
165 | spin_lock_irq(phba->host->host_lock); | ||
166 | lpfc_sli_release_iocbq(phba, elsiocb); | 159 | lpfc_sli_release_iocbq(phba, elsiocb); |
167 | spin_unlock_irq(phba->host->host_lock); | ||
168 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); | 160 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); |
169 | lpfc_mbuf_free(phba, prsp->virt, prsp->phys); | 161 | lpfc_mbuf_free(phba, prsp->virt, prsp->phys); |
170 | kfree(pcmd); | 162 | kfree(pcmd); |
@@ -178,9 +170,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | |||
178 | icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); | 170 | icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); |
179 | icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys); | 171 | icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys); |
180 | icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL; | 172 | icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL; |
173 | icmd->un.elsreq64.remoteID = did; /* DID */ | ||
181 | if (expectRsp) { | 174 | if (expectRsp) { |
182 | icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); | 175 | icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); |
183 | icmd->un.elsreq64.remoteID = did; /* DID */ | ||
184 | icmd->ulpCommand = CMD_ELS_REQUEST64_CR; | 176 | icmd->ulpCommand = CMD_ELS_REQUEST64_CR; |
185 | icmd->ulpTimeout = phba->fc_ratov * 2; | 177 | icmd->ulpTimeout = phba->fc_ratov * 2; |
186 | } else { | 178 | } else { |
@@ -213,6 +205,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | |||
213 | elsiocb->context2 = pcmd; | 205 | elsiocb->context2 = pcmd; |
214 | elsiocb->context3 = pbuflist; | 206 | elsiocb->context3 = pbuflist; |
215 | elsiocb->retry = retry; | 207 | elsiocb->retry = retry; |
208 | elsiocb->vport = vport; | ||
216 | elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT; | 209 | elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT; |
217 | 210 | ||
218 | if (prsp) { | 211 | if (prsp) { |
@@ -223,9 +216,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | |||
223 | /* Xmit ELS command <elsCmd> to remote NPORT <did> */ | 216 | /* Xmit ELS command <elsCmd> to remote NPORT <did> */ |
224 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 217 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
225 | "%d:0116 Xmit ELS command x%x to remote " | 218 | "%d:0116 Xmit ELS command x%x to remote " |
226 | "NPORT x%x I/O tag: x%x, HBA state: x%x\n", | 219 | "NPORT x%x I/O tag: x%x, port state: x%x\n", |
227 | phba->brd_no, elscmd, | 220 | phba->brd_no, elscmd, did, |
228 | did, elsiocb->iotag, phba->hba_state); | 221 | elsiocb->iotag, vport->port_state); |
229 | } else { | 222 | } else { |
230 | /* Xmit ELS response <elsCmd> to remote NPORT <did> */ | 223 | /* Xmit ELS response <elsCmd> to remote NPORT <did> */ |
231 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 224 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -240,16 +233,18 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | |||
240 | 233 | ||
241 | 234 | ||
242 | static int | 235 | static int |
243 | lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | 236 | lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
244 | struct serv_parm *sp, IOCB_t *irsp) | 237 | struct serv_parm *sp, IOCB_t *irsp) |
245 | { | 238 | { |
239 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
240 | struct lpfc_hba *phba = vport->phba; | ||
246 | LPFC_MBOXQ_t *mbox; | 241 | LPFC_MBOXQ_t *mbox; |
247 | struct lpfc_dmabuf *mp; | 242 | struct lpfc_dmabuf *mp; |
248 | int rc; | 243 | int rc; |
249 | 244 | ||
250 | spin_lock_irq(phba->host->host_lock); | 245 | spin_lock_irq(shost->host_lock); |
251 | phba->fc_flag |= FC_FABRIC; | 246 | vport->fc_flag |= FC_FABRIC; |
252 | spin_unlock_irq(phba->host->host_lock); | 247 | spin_unlock_irq(shost->host_lock); |
253 | 248 | ||
254 | phba->fc_edtov = be32_to_cpu(sp->cmn.e_d_tov); | 249 | phba->fc_edtov = be32_to_cpu(sp->cmn.e_d_tov); |
255 | if (sp->cmn.edtovResolution) /* E_D_TOV ticks are in nanoseconds */ | 250 | if (sp->cmn.edtovResolution) /* E_D_TOV ticks are in nanoseconds */ |
@@ -258,18 +253,18 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
258 | phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000; | 253 | phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000; |
259 | 254 | ||
260 | if (phba->fc_topology == TOPOLOGY_LOOP) { | 255 | if (phba->fc_topology == TOPOLOGY_LOOP) { |
261 | spin_lock_irq(phba->host->host_lock); | 256 | spin_lock_irq(shost->host_lock); |
262 | phba->fc_flag |= FC_PUBLIC_LOOP; | 257 | vport->fc_flag |= FC_PUBLIC_LOOP; |
263 | spin_unlock_irq(phba->host->host_lock); | 258 | spin_unlock_irq(shost->host_lock); |
264 | } else { | 259 | } else { |
265 | /* | 260 | /* |
266 | * If we are a N-port connected to a Fabric, fixup sparam's so | 261 | * If we are a N-port connected to a Fabric, fixup sparam's so |
267 | * logins to devices on remote loops work. | 262 | * logins to devices on remote loops work. |
268 | */ | 263 | */ |
269 | phba->fc_sparam.cmn.altBbCredit = 1; | 264 | vport->fc_sparam.cmn.altBbCredit = 1; |
270 | } | 265 | } |
271 | 266 | ||
272 | phba->fc_myDID = irsp->un.ulpWord[4] & Mask_DID; | 267 | vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID; |
273 | memcpy(&ndlp->nlp_portname, &sp->portName, sizeof(struct lpfc_name)); | 268 | memcpy(&ndlp->nlp_portname, &sp->portName, sizeof(struct lpfc_name)); |
274 | memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name)); | 269 | memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name)); |
275 | ndlp->nlp_class_sup = 0; | 270 | ndlp->nlp_class_sup = 0; |
@@ -285,11 +280,13 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
285 | sp->cmn.bbRcvSizeLsb; | 280 | sp->cmn.bbRcvSizeLsb; |
286 | memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); | 281 | memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); |
287 | 282 | ||
283 | ndlp->nlp_sid = irsp->un.ulpWord[4] & Mask_DID; | ||
284 | |||
288 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 285 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
289 | if (!mbox) | 286 | if (!mbox) |
290 | goto fail; | 287 | goto fail; |
291 | 288 | ||
292 | phba->hba_state = LPFC_FABRIC_CFG_LINK; | 289 | vport->port_state = LPFC_FABRIC_CFG_LINK; |
293 | lpfc_config_link(phba, mbox); | 290 | lpfc_config_link(phba, mbox); |
294 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 291 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
295 | 292 | ||
@@ -300,11 +297,12 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
300 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 297 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
301 | if (!mbox) | 298 | if (!mbox) |
302 | goto fail; | 299 | goto fail; |
303 | 300 | rc = lpfc_reg_login(phba, Fabric_DID, (uint8_t *) sp, mbox, 0); | |
304 | if (lpfc_reg_login(phba, Fabric_DID, (uint8_t *) sp, mbox, 0)) | 301 | if (rc) |
305 | goto fail_free_mbox; | 302 | goto fail_free_mbox; |
306 | 303 | ||
307 | mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; | 304 | mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; |
305 | mbox->vport = vport; | ||
308 | mbox->context2 = lpfc_nlp_get(ndlp); | 306 | mbox->context2 = lpfc_nlp_get(ndlp); |
309 | 307 | ||
310 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); | 308 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); |
@@ -328,25 +326,27 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
328 | * We FLOGIed into an NPort, initiate pt2pt protocol | 326 | * We FLOGIed into an NPort, initiate pt2pt protocol |
329 | */ | 327 | */ |
330 | static int | 328 | static int |
331 | lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | 329 | lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
332 | struct serv_parm *sp) | 330 | struct serv_parm *sp) |
333 | { | 331 | { |
332 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
333 | struct lpfc_hba *phba = vport->phba; | ||
334 | LPFC_MBOXQ_t *mbox; | 334 | LPFC_MBOXQ_t *mbox; |
335 | int rc; | 335 | int rc; |
336 | 336 | ||
337 | spin_lock_irq(phba->host->host_lock); | 337 | spin_lock_irq(shost->host_lock); |
338 | phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); | 338 | vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); |
339 | spin_unlock_irq(phba->host->host_lock); | 339 | spin_unlock_irq(shost->host_lock); |
340 | 340 | ||
341 | phba->fc_edtov = FF_DEF_EDTOV; | 341 | phba->fc_edtov = FF_DEF_EDTOV; |
342 | phba->fc_ratov = FF_DEF_RATOV; | 342 | phba->fc_ratov = FF_DEF_RATOV; |
343 | rc = memcmp(&phba->fc_portname, &sp->portName, | 343 | rc = memcmp(&vport->fc_portname, &sp->portName, |
344 | sizeof(struct lpfc_name)); | 344 | sizeof(struct lpfc_name)); |
345 | if (rc >= 0) { | 345 | if (rc >= 0) { |
346 | /* This side will initiate the PLOGI */ | 346 | /* This side will initiate the PLOGI */ |
347 | spin_lock_irq(phba->host->host_lock); | 347 | spin_lock_irq(shost->host_lock); |
348 | phba->fc_flag |= FC_PT2PT_PLOGI; | 348 | vport->fc_flag |= FC_PT2PT_PLOGI; |
349 | spin_unlock_irq(phba->host->host_lock); | 349 | spin_unlock_irq(shost->host_lock); |
350 | 350 | ||
351 | /* | 351 | /* |
352 | * N_Port ID cannot be 0, set our to LocalID the other | 352 | * N_Port ID cannot be 0, set our to LocalID the other |
@@ -355,7 +355,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
355 | 355 | ||
356 | /* not equal */ | 356 | /* not equal */ |
357 | if (rc) | 357 | if (rc) |
358 | phba->fc_myDID = PT2PT_LocalID; | 358 | vport->fc_myDID = PT2PT_LocalID; |
359 | 359 | ||
360 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 360 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
361 | if (!mbox) | 361 | if (!mbox) |
@@ -372,7 +372,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
372 | } | 372 | } |
373 | lpfc_nlp_put(ndlp); | 373 | lpfc_nlp_put(ndlp); |
374 | 374 | ||
375 | ndlp = lpfc_findnode_did(phba, PT2PT_RemoteID); | 375 | ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID); |
376 | if (!ndlp) { | 376 | if (!ndlp) { |
377 | /* | 377 | /* |
378 | * Cannot find existing Fabric ndlp, so allocate a | 378 | * Cannot find existing Fabric ndlp, so allocate a |
@@ -382,26 +382,28 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
382 | if (!ndlp) | 382 | if (!ndlp) |
383 | goto fail; | 383 | goto fail; |
384 | 384 | ||
385 | lpfc_nlp_init(phba, ndlp, PT2PT_RemoteID); | 385 | lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID); |
386 | } | 386 | } |
387 | 387 | ||
388 | memcpy(&ndlp->nlp_portname, &sp->portName, | 388 | memcpy(&ndlp->nlp_portname, &sp->portName, |
389 | sizeof(struct lpfc_name)); | 389 | sizeof(struct lpfc_name)); |
390 | memcpy(&ndlp->nlp_nodename, &sp->nodeName, | 390 | memcpy(&ndlp->nlp_nodename, &sp->nodeName, |
391 | sizeof(struct lpfc_name)); | 391 | sizeof(struct lpfc_name)); |
392 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 392 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
393 | spin_lock_irq(shost->host_lock); | ||
393 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 394 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
395 | spin_unlock_irq(shost->host_lock); | ||
394 | } else { | 396 | } else { |
395 | /* This side will wait for the PLOGI */ | 397 | /* This side will wait for the PLOGI */ |
396 | lpfc_nlp_put(ndlp); | 398 | lpfc_nlp_put(ndlp); |
397 | } | 399 | } |
398 | 400 | ||
399 | spin_lock_irq(phba->host->host_lock); | 401 | spin_lock_irq(shost->host_lock); |
400 | phba->fc_flag |= FC_PT2PT; | 402 | vport->fc_flag |= FC_PT2PT; |
401 | spin_unlock_irq(phba->host->host_lock); | 403 | spin_unlock_irq(shost->host_lock); |
402 | 404 | ||
403 | /* Start discovery - this should just do CLEAR_LA */ | 405 | /* Start discovery - this should just do CLEAR_LA */ |
404 | lpfc_disc_start(phba); | 406 | lpfc_disc_start(vport); |
405 | return 0; | 407 | return 0; |
406 | fail: | 408 | fail: |
407 | return -ENXIO; | 409 | return -ENXIO; |
@@ -411,6 +413,8 @@ static void | |||
411 | lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 413 | lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
412 | struct lpfc_iocbq *rspiocb) | 414 | struct lpfc_iocbq *rspiocb) |
413 | { | 415 | { |
416 | struct lpfc_vport *vport = cmdiocb->vport; | ||
417 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
414 | IOCB_t *irsp = &rspiocb->iocb; | 418 | IOCB_t *irsp = &rspiocb->iocb; |
415 | struct lpfc_nodelist *ndlp = cmdiocb->context1; | 419 | struct lpfc_nodelist *ndlp = cmdiocb->context1; |
416 | struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp; | 420 | struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp; |
@@ -418,21 +422,20 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
418 | int rc; | 422 | int rc; |
419 | 423 | ||
420 | /* Check to see if link went down during discovery */ | 424 | /* Check to see if link went down during discovery */ |
421 | if (lpfc_els_chk_latt(phba)) { | 425 | if (lpfc_els_chk_latt(vport)) { |
422 | lpfc_nlp_put(ndlp); | 426 | lpfc_nlp_put(ndlp); |
423 | goto out; | 427 | goto out; |
424 | } | 428 | } |
425 | 429 | ||
426 | if (irsp->ulpStatus) { | 430 | if (irsp->ulpStatus) { |
427 | /* Check for retry */ | 431 | /* Check for retry */ |
428 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) { | 432 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) |
429 | /* ELS command is being retried */ | ||
430 | goto out; | 433 | goto out; |
431 | } | 434 | |
432 | /* FLOGI failed, so there is no fabric */ | 435 | /* FLOGI failed, so there is no fabric */ |
433 | spin_lock_irq(phba->host->host_lock); | 436 | spin_lock_irq(shost->host_lock); |
434 | phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); | 437 | vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); |
435 | spin_unlock_irq(phba->host->host_lock); | 438 | spin_unlock_irq(shost->host_lock); |
436 | 439 | ||
437 | /* If private loop, then allow max outstanding els to be | 440 | /* If private loop, then allow max outstanding els to be |
438 | * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no | 441 | * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no |
@@ -469,15 +472,15 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
469 | irsp->un.ulpWord[4], sp->cmn.e_d_tov, | 472 | irsp->un.ulpWord[4], sp->cmn.e_d_tov, |
470 | sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution); | 473 | sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution); |
471 | 474 | ||
472 | if (phba->hba_state == LPFC_FLOGI) { | 475 | if (vport->port_state == LPFC_FLOGI) { |
473 | /* | 476 | /* |
474 | * If Common Service Parameters indicate Nport | 477 | * If Common Service Parameters indicate Nport |
475 | * we are point to point, if Fport we are Fabric. | 478 | * we are point to point, if Fport we are Fabric. |
476 | */ | 479 | */ |
477 | if (sp->cmn.fPort) | 480 | if (sp->cmn.fPort) |
478 | rc = lpfc_cmpl_els_flogi_fabric(phba, ndlp, sp, irsp); | 481 | rc = lpfc_cmpl_els_flogi_fabric(vport, ndlp, sp, irsp); |
479 | else | 482 | else |
480 | rc = lpfc_cmpl_els_flogi_nport(phba, ndlp, sp); | 483 | rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); |
481 | 484 | ||
482 | if (!rc) | 485 | if (!rc) |
483 | goto out; | 486 | goto out; |
@@ -490,10 +493,10 @@ flogifail: | |||
490 | (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED && | 493 | (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED && |
491 | irsp->un.ulpWord[4] != IOERR_SLI_DOWN)) { | 494 | irsp->un.ulpWord[4] != IOERR_SLI_DOWN)) { |
492 | /* FLOGI failed, so just use loop map to make discovery list */ | 495 | /* FLOGI failed, so just use loop map to make discovery list */ |
493 | lpfc_disc_list_loopmap(phba); | 496 | lpfc_disc_list_loopmap(vport); |
494 | 497 | ||
495 | /* Start discovery */ | 498 | /* Start discovery */ |
496 | lpfc_disc_start(phba); | 499 | lpfc_disc_start(vport); |
497 | } | 500 | } |
498 | 501 | ||
499 | out: | 502 | out: |
@@ -501,9 +504,10 @@ out: | |||
501 | } | 504 | } |
502 | 505 | ||
503 | static int | 506 | static int |
504 | lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | 507 | lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
505 | uint8_t retry) | 508 | uint8_t retry) |
506 | { | 509 | { |
510 | struct lpfc_hba *phba = vport->phba; | ||
507 | struct serv_parm *sp; | 511 | struct serv_parm *sp; |
508 | IOCB_t *icmd; | 512 | IOCB_t *icmd; |
509 | struct lpfc_iocbq *elsiocb; | 513 | struct lpfc_iocbq *elsiocb; |
@@ -516,8 +520,8 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
516 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 520 | pring = &phba->sli.ring[LPFC_ELS_RING]; |
517 | 521 | ||
518 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); | 522 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); |
519 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, | 523 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, |
520 | ndlp->nlp_DID, ELS_CMD_FLOGI); | 524 | ndlp->nlp_DID, ELS_CMD_FLOGI); |
521 | if (!elsiocb) | 525 | if (!elsiocb) |
522 | return 1; | 526 | return 1; |
523 | 527 | ||
@@ -527,7 +531,7 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
527 | /* For FLOGI request, remainder of payload is service parameters */ | 531 | /* For FLOGI request, remainder of payload is service parameters */ |
528 | *((uint32_t *) (pcmd)) = ELS_CMD_FLOGI; | 532 | *((uint32_t *) (pcmd)) = ELS_CMD_FLOGI; |
529 | pcmd += sizeof (uint32_t); | 533 | pcmd += sizeof (uint32_t); |
530 | memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); | 534 | memcpy(pcmd, &vport->fc_sparam, sizeof (struct serv_parm)); |
531 | sp = (struct serv_parm *) pcmd; | 535 | sp = (struct serv_parm *) pcmd; |
532 | 536 | ||
533 | /* Setup CSPs accordingly for Fabric */ | 537 | /* Setup CSPs accordingly for Fabric */ |
@@ -543,14 +547,12 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
543 | 547 | ||
544 | tmo = phba->fc_ratov; | 548 | tmo = phba->fc_ratov; |
545 | phba->fc_ratov = LPFC_DISC_FLOGI_TMO; | 549 | phba->fc_ratov = LPFC_DISC_FLOGI_TMO; |
546 | lpfc_set_disctmo(phba); | 550 | lpfc_set_disctmo(vport); |
547 | phba->fc_ratov = tmo; | 551 | phba->fc_ratov = tmo; |
548 | 552 | ||
549 | phba->fc_stat.elsXmitFLOGI++; | 553 | phba->fc_stat.elsXmitFLOGI++; |
550 | elsiocb->iocb_cmpl = lpfc_cmpl_els_flogi; | 554 | elsiocb->iocb_cmpl = lpfc_cmpl_els_flogi; |
551 | spin_lock_irq(phba->host->host_lock); | ||
552 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 555 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
553 | spin_unlock_irq(phba->host->host_lock); | ||
554 | if (rc == IOCB_ERROR) { | 556 | if (rc == IOCB_ERROR) { |
555 | lpfc_els_free_iocb(phba, elsiocb); | 557 | lpfc_els_free_iocb(phba, elsiocb); |
556 | return 1; | 558 | return 1; |
@@ -559,7 +561,7 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
559 | } | 561 | } |
560 | 562 | ||
561 | int | 563 | int |
562 | lpfc_els_abort_flogi(struct lpfc_hba * phba) | 564 | lpfc_els_abort_flogi(struct lpfc_hba *phba) |
563 | { | 565 | { |
564 | struct lpfc_sli_ring *pring; | 566 | struct lpfc_sli_ring *pring; |
565 | struct lpfc_iocbq *iocb, *next_iocb; | 567 | struct lpfc_iocbq *iocb, *next_iocb; |
@@ -577,62 +579,65 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba) | |||
577 | * Check the txcmplq for an iocb that matches the nport the driver is | 579 | * Check the txcmplq for an iocb that matches the nport the driver is |
578 | * searching for. | 580 | * searching for. |
579 | */ | 581 | */ |
580 | spin_lock_irq(phba->host->host_lock); | 582 | spin_lock_irq(&phba->hbalock); |
581 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { | 583 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { |
582 | icmd = &iocb->iocb; | 584 | icmd = &iocb->iocb; |
583 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) { | 585 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && |
586 | icmd->un.elsreq64.bdl.ulpIoTag32) { | ||
584 | ndlp = (struct lpfc_nodelist *)(iocb->context1); | 587 | ndlp = (struct lpfc_nodelist *)(iocb->context1); |
585 | if (ndlp && (ndlp->nlp_DID == Fabric_DID)) | 588 | if (ndlp && (ndlp->nlp_DID == Fabric_DID)) |
586 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); | 589 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
587 | } | 590 | } |
588 | } | 591 | } |
589 | spin_unlock_irq(phba->host->host_lock); | 592 | spin_unlock_irq(&phba->hbalock); |
590 | 593 | ||
591 | return 0; | 594 | return 0; |
592 | } | 595 | } |
593 | 596 | ||
594 | int | 597 | int |
595 | lpfc_initial_flogi(struct lpfc_hba *phba) | 598 | lpfc_initial_flogi(struct lpfc_vport *vport) |
596 | { | 599 | { |
600 | struct lpfc_hba *phba = vport->phba; | ||
597 | struct lpfc_nodelist *ndlp; | 601 | struct lpfc_nodelist *ndlp; |
598 | 602 | ||
599 | /* First look for the Fabric ndlp */ | 603 | /* First look for the Fabric ndlp */ |
600 | ndlp = lpfc_findnode_did(phba, Fabric_DID); | 604 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
601 | if (!ndlp) { | 605 | if (!ndlp) { |
602 | /* Cannot find existing Fabric ndlp, so allocate a new one */ | 606 | /* Cannot find existing Fabric ndlp, so allocate a new one */ |
603 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | 607 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
604 | if (!ndlp) | 608 | if (!ndlp) |
605 | return 0; | 609 | return 0; |
606 | lpfc_nlp_init(phba, ndlp, Fabric_DID); | 610 | lpfc_nlp_init(vport, ndlp, Fabric_DID); |
607 | } else { | 611 | } else { |
608 | lpfc_dequeue_node(phba, ndlp); | 612 | lpfc_dequeue_node(vport, ndlp); |
609 | } | 613 | } |
610 | if (lpfc_issue_els_flogi(phba, ndlp, 0)) { | 614 | if (lpfc_issue_els_flogi(vport, ndlp, 0)) { |
611 | lpfc_nlp_put(ndlp); | 615 | lpfc_nlp_put(ndlp); |
612 | } | 616 | } |
613 | return 1; | 617 | return 1; |
614 | } | 618 | } |
615 | 619 | ||
616 | static void | 620 | static void |
617 | lpfc_more_plogi(struct lpfc_hba * phba) | 621 | lpfc_more_plogi(struct lpfc_vport *vport) |
618 | { | 622 | { |
619 | int sentplogi; | 623 | int sentplogi; |
624 | struct lpfc_hba *phba = vport->phba; | ||
620 | 625 | ||
621 | if (phba->num_disc_nodes) | 626 | if (vport->num_disc_nodes) |
622 | phba->num_disc_nodes--; | 627 | vport->num_disc_nodes--; |
623 | 628 | ||
624 | /* Continue discovery with <num_disc_nodes> PLOGIs to go */ | 629 | /* Continue discovery with <num_disc_nodes> PLOGIs to go */ |
625 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 630 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
626 | "%d:0232 Continue discovery with %d PLOGIs to go " | 631 | "%d:0232 Continue discovery with %d PLOGIs to go " |
627 | "Data: x%x x%x x%x\n", | 632 | "Data: x%x x%x x%x\n", |
628 | phba->brd_no, phba->num_disc_nodes, phba->fc_plogi_cnt, | 633 | phba->brd_no, vport->num_disc_nodes, |
629 | phba->fc_flag, phba->hba_state); | 634 | vport->fc_plogi_cnt, vport->fc_flag, vport->port_state); |
630 | 635 | ||
631 | /* Check to see if there are more PLOGIs to be sent */ | 636 | /* Check to see if there are more PLOGIs to be sent */ |
632 | if (phba->fc_flag & FC_NLP_MORE) { | 637 | if (vport->fc_flag & FC_NLP_MORE) |
633 | /* go thru NPR list and issue any remaining ELS PLOGIs */ | 638 | /* go thru NPR nodes and issue any remaining ELS PLOGIs */ |
634 | sentplogi = lpfc_els_disc_plogi(phba); | 639 | sentplogi = lpfc_els_disc_plogi(vport); |
635 | } | 640 | |
636 | return; | 641 | return; |
637 | } | 642 | } |
638 | 643 | ||
@@ -640,6 +645,7 @@ static struct lpfc_nodelist * | |||
640 | lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp, | 645 | lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp, |
641 | struct lpfc_nodelist *ndlp) | 646 | struct lpfc_nodelist *ndlp) |
642 | { | 647 | { |
648 | struct lpfc_vport *vport = ndlp->vport; | ||
643 | struct lpfc_nodelist *new_ndlp; | 649 | struct lpfc_nodelist *new_ndlp; |
644 | uint32_t *lp; | 650 | uint32_t *lp; |
645 | struct serv_parm *sp; | 651 | struct serv_parm *sp; |
@@ -659,43 +665,45 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp, | |||
659 | /* Now we find out if the NPort we are logging into, matches the WWPN | 665 | /* Now we find out if the NPort we are logging into, matches the WWPN |
660 | * we have for that ndlp. If not, we have some work to do. | 666 | * we have for that ndlp. If not, we have some work to do. |
661 | */ | 667 | */ |
662 | new_ndlp = lpfc_findnode_wwpn(phba, &sp->portName); | 668 | new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName); |
663 | 669 | ||
664 | if (new_ndlp == ndlp) | 670 | if (new_ndlp == ndlp) |
665 | return ndlp; | 671 | return ndlp; |
666 | 672 | ||
667 | if (!new_ndlp) { | 673 | if (!new_ndlp) { |
668 | rc = | 674 | rc = memcmp(&ndlp->nlp_portname, name, |
669 | memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); | 675 | sizeof(struct lpfc_name)); |
670 | if (!rc) | 676 | if (!rc) |
671 | return ndlp; | 677 | return ndlp; |
672 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); | 678 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); |
673 | if (!new_ndlp) | 679 | if (!new_ndlp) |
674 | return ndlp; | 680 | return ndlp; |
675 | 681 | ||
676 | lpfc_nlp_init(phba, new_ndlp, ndlp->nlp_DID); | 682 | lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); |
677 | } | 683 | } |
678 | 684 | ||
679 | lpfc_unreg_rpi(phba, new_ndlp); | 685 | lpfc_unreg_rpi(vport, new_ndlp); |
680 | new_ndlp->nlp_DID = ndlp->nlp_DID; | 686 | new_ndlp->nlp_DID = ndlp->nlp_DID; |
681 | new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; | 687 | new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; |
682 | lpfc_nlp_set_state(phba, new_ndlp, ndlp->nlp_state); | 688 | lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state); |
683 | 689 | ||
684 | /* Move this back to NPR list */ | 690 | /* Move this back to NPR state */ |
685 | if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) | 691 | if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) |
686 | lpfc_drop_node(phba, ndlp); | 692 | lpfc_drop_node(vport, ndlp); |
687 | else { | 693 | else { |
688 | lpfc_unreg_rpi(phba, ndlp); | 694 | lpfc_unreg_rpi(vport, ndlp); |
689 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | 695 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ |
690 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 696 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
691 | } | 697 | } |
692 | return new_ndlp; | 698 | return new_ndlp; |
693 | } | 699 | } |
694 | 700 | ||
695 | static void | 701 | static void |
696 | lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 702 | lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
697 | struct lpfc_iocbq * rspiocb) | 703 | struct lpfc_iocbq *rspiocb) |
698 | { | 704 | { |
705 | struct lpfc_vport *vport = cmdiocb->vport; | ||
706 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
699 | IOCB_t *irsp; | 707 | IOCB_t *irsp; |
700 | struct lpfc_nodelist *ndlp; | 708 | struct lpfc_nodelist *ndlp; |
701 | struct lpfc_dmabuf *prsp; | 709 | struct lpfc_dmabuf *prsp; |
@@ -705,17 +713,17 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
705 | cmdiocb->context_un.rsp_iocb = rspiocb; | 713 | cmdiocb->context_un.rsp_iocb = rspiocb; |
706 | 714 | ||
707 | irsp = &rspiocb->iocb; | 715 | irsp = &rspiocb->iocb; |
708 | ndlp = lpfc_findnode_did(phba, irsp->un.elsreq64.remoteID); | 716 | ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID); |
709 | if (!ndlp) | 717 | if (!ndlp) |
710 | goto out; | 718 | goto out; |
711 | 719 | ||
712 | /* Since ndlp can be freed in the disc state machine, note if this node | 720 | /* Since ndlp can be freed in the disc state machine, note if this node |
713 | * is being used during discovery. | 721 | * is being used during discovery. |
714 | */ | 722 | */ |
723 | spin_lock_irq(shost->host_lock); | ||
715 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); | 724 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); |
716 | spin_lock_irq(phba->host->host_lock); | ||
717 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 725 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
718 | spin_unlock_irq(phba->host->host_lock); | 726 | spin_unlock_irq(shost->host_lock); |
719 | rc = 0; | 727 | rc = 0; |
720 | 728 | ||
721 | /* PLOGI completes to NPort <nlp_DID> */ | 729 | /* PLOGI completes to NPort <nlp_DID> */ |
@@ -724,13 +732,13 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
724 | "Data: x%x x%x x%x x%x x%x\n", | 732 | "Data: x%x x%x x%x x%x x%x\n", |
725 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, | 733 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, |
726 | irsp->un.ulpWord[4], irsp->ulpTimeout, disc, | 734 | irsp->un.ulpWord[4], irsp->ulpTimeout, disc, |
727 | phba->num_disc_nodes); | 735 | vport->num_disc_nodes); |
728 | 736 | ||
729 | /* Check to see if link went down during discovery */ | 737 | /* Check to see if link went down during discovery */ |
730 | if (lpfc_els_chk_latt(phba)) { | 738 | if (lpfc_els_chk_latt(vport)) { |
731 | spin_lock_irq(phba->host->host_lock); | 739 | spin_lock_irq(shost->host_lock); |
732 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 740 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
733 | spin_unlock_irq(phba->host->host_lock); | 741 | spin_unlock_irq(shost->host_lock); |
734 | goto out; | 742 | goto out; |
735 | } | 743 | } |
736 | 744 | ||
@@ -743,9 +751,9 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
743 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) { | 751 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) { |
744 | /* ELS command is being retried */ | 752 | /* ELS command is being retried */ |
745 | if (disc) { | 753 | if (disc) { |
746 | spin_lock_irq(phba->host->host_lock); | 754 | spin_lock_irq(shost->host_lock); |
747 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 755 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
748 | spin_unlock_irq(phba->host->host_lock); | 756 | spin_unlock_irq(shost->host_lock); |
749 | } | 757 | } |
750 | goto out; | 758 | goto out; |
751 | } | 759 | } |
@@ -758,7 +766,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
758 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { | 766 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { |
759 | rc = NLP_STE_FREED_NODE; | 767 | rc = NLP_STE_FREED_NODE; |
760 | } else { | 768 | } else { |
761 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 769 | rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
762 | NLP_EVT_CMPL_PLOGI); | 770 | NLP_EVT_CMPL_PLOGI); |
763 | } | 771 | } |
764 | } else { | 772 | } else { |
@@ -767,32 +775,32 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
767 | cmdiocb->context2)->list.next, | 775 | cmdiocb->context2)->list.next, |
768 | struct lpfc_dmabuf, list); | 776 | struct lpfc_dmabuf, list); |
769 | ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp); | 777 | ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp); |
770 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 778 | rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
771 | NLP_EVT_CMPL_PLOGI); | 779 | NLP_EVT_CMPL_PLOGI); |
772 | } | 780 | } |
773 | 781 | ||
774 | if (disc && phba->num_disc_nodes) { | 782 | if (disc && vport->num_disc_nodes) { |
775 | /* Check to see if there are more PLOGIs to be sent */ | 783 | /* Check to see if there are more PLOGIs to be sent */ |
776 | lpfc_more_plogi(phba); | 784 | lpfc_more_plogi(vport); |
777 | 785 | ||
778 | if (phba->num_disc_nodes == 0) { | 786 | if (vport->num_disc_nodes == 0) { |
779 | spin_lock_irq(phba->host->host_lock); | 787 | spin_lock_irq(shost->host_lock); |
780 | phba->fc_flag &= ~FC_NDISC_ACTIVE; | 788 | vport->fc_flag &= ~FC_NDISC_ACTIVE; |
781 | spin_unlock_irq(phba->host->host_lock); | 789 | spin_unlock_irq(shost->host_lock); |
782 | 790 | ||
783 | lpfc_can_disctmo(phba); | 791 | lpfc_can_disctmo(vport); |
784 | if (phba->fc_flag & FC_RSCN_MODE) { | 792 | if (vport->fc_flag & FC_RSCN_MODE) { |
785 | /* | 793 | /* |
786 | * Check to see if more RSCNs came in while | 794 | * Check to see if more RSCNs came in while |
787 | * we were processing this one. | 795 | * we were processing this one. |
788 | */ | 796 | */ |
789 | if ((phba->fc_rscn_id_cnt == 0) && | 797 | if ((vport->fc_rscn_id_cnt == 0) && |
790 | (!(phba->fc_flag & FC_RSCN_DISCOVERY))) { | 798 | (!(vport->fc_flag & FC_RSCN_DISCOVERY))) { |
791 | spin_lock_irq(phba->host->host_lock); | 799 | spin_lock_irq(shost->host_lock); |
792 | phba->fc_flag &= ~FC_RSCN_MODE; | 800 | vport->fc_flag &= ~FC_RSCN_MODE; |
793 | spin_unlock_irq(phba->host->host_lock); | 801 | spin_unlock_irq(shost->host_lock); |
794 | } else { | 802 | } else { |
795 | lpfc_els_handle_rscn(phba); | 803 | lpfc_els_handle_rscn(vport); |
796 | } | 804 | } |
797 | } | 805 | } |
798 | } | 806 | } |
@@ -804,8 +812,9 @@ out: | |||
804 | } | 812 | } |
805 | 813 | ||
806 | int | 814 | int |
807 | lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) | 815 | lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) |
808 | { | 816 | { |
817 | struct lpfc_hba *phba = vport->phba; | ||
809 | struct serv_parm *sp; | 818 | struct serv_parm *sp; |
810 | IOCB_t *icmd; | 819 | IOCB_t *icmd; |
811 | struct lpfc_iocbq *elsiocb; | 820 | struct lpfc_iocbq *elsiocb; |
@@ -818,8 +827,8 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) | |||
818 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 827 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
819 | 828 | ||
820 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); | 829 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); |
821 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, NULL, did, | 830 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, NULL, did, |
822 | ELS_CMD_PLOGI); | 831 | ELS_CMD_PLOGI); |
823 | if (!elsiocb) | 832 | if (!elsiocb) |
824 | return 1; | 833 | return 1; |
825 | 834 | ||
@@ -829,7 +838,7 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) | |||
829 | /* For PLOGI request, remainder of payload is service parameters */ | 838 | /* For PLOGI request, remainder of payload is service parameters */ |
830 | *((uint32_t *) (pcmd)) = ELS_CMD_PLOGI; | 839 | *((uint32_t *) (pcmd)) = ELS_CMD_PLOGI; |
831 | pcmd += sizeof (uint32_t); | 840 | pcmd += sizeof (uint32_t); |
832 | memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); | 841 | memcpy(pcmd, &vport->fc_sparam, sizeof (struct serv_parm)); |
833 | sp = (struct serv_parm *) pcmd; | 842 | sp = (struct serv_parm *) pcmd; |
834 | 843 | ||
835 | if (sp->cmn.fcphLow < FC_PH_4_3) | 844 | if (sp->cmn.fcphLow < FC_PH_4_3) |
@@ -840,20 +849,19 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) | |||
840 | 849 | ||
841 | phba->fc_stat.elsXmitPLOGI++; | 850 | phba->fc_stat.elsXmitPLOGI++; |
842 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; | 851 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; |
843 | spin_lock_irq(phba->host->host_lock); | ||
844 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 852 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
845 | spin_unlock_irq(phba->host->host_lock); | ||
846 | lpfc_els_free_iocb(phba, elsiocb); | 853 | lpfc_els_free_iocb(phba, elsiocb); |
847 | return 1; | 854 | return 1; |
848 | } | 855 | } |
849 | spin_unlock_irq(phba->host->host_lock); | ||
850 | return 0; | 856 | return 0; |
851 | } | 857 | } |
852 | 858 | ||
853 | static void | 859 | static void |
854 | lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 860 | lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
855 | struct lpfc_iocbq * rspiocb) | 861 | struct lpfc_iocbq *rspiocb) |
856 | { | 862 | { |
863 | struct lpfc_vport *vport = cmdiocb->vport; | ||
864 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
857 | IOCB_t *irsp; | 865 | IOCB_t *irsp; |
858 | struct lpfc_sli *psli; | 866 | struct lpfc_sli *psli; |
859 | struct lpfc_nodelist *ndlp; | 867 | struct lpfc_nodelist *ndlp; |
@@ -864,9 +872,9 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
864 | 872 | ||
865 | irsp = &(rspiocb->iocb); | 873 | irsp = &(rspiocb->iocb); |
866 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 874 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
867 | spin_lock_irq(phba->host->host_lock); | 875 | spin_lock_irq(shost->host_lock); |
868 | ndlp->nlp_flag &= ~NLP_PRLI_SND; | 876 | ndlp->nlp_flag &= ~NLP_PRLI_SND; |
869 | spin_unlock_irq(phba->host->host_lock); | 877 | spin_unlock_irq(shost->host_lock); |
870 | 878 | ||
871 | /* PRLI completes to NPort <nlp_DID> */ | 879 | /* PRLI completes to NPort <nlp_DID> */ |
872 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 880 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -874,11 +882,11 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
874 | "Data: x%x x%x x%x x%x\n", | 882 | "Data: x%x x%x x%x x%x\n", |
875 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, | 883 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, |
876 | irsp->un.ulpWord[4], irsp->ulpTimeout, | 884 | irsp->un.ulpWord[4], irsp->ulpTimeout, |
877 | phba->num_disc_nodes); | 885 | vport->num_disc_nodes); |
878 | 886 | ||
879 | phba->fc_prli_sent--; | 887 | vport->fc_prli_sent--; |
880 | /* Check to see if link went down during discovery */ | 888 | /* Check to see if link went down during discovery */ |
881 | if (lpfc_els_chk_latt(phba)) | 889 | if (lpfc_els_chk_latt(vport)) |
882 | goto out; | 890 | goto out; |
883 | 891 | ||
884 | if (irsp->ulpStatus) { | 892 | if (irsp->ulpStatus) { |
@@ -895,12 +903,13 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
895 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { | 903 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { |
896 | goto out; | 904 | goto out; |
897 | } else { | 905 | } else { |
898 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 906 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
899 | NLP_EVT_CMPL_PRLI); | 907 | NLP_EVT_CMPL_PRLI); |
900 | } | 908 | } |
901 | } else { | 909 | } else { |
902 | /* Good status, call state machine */ | 910 | /* Good status, call state machine */ |
903 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_PRLI); | 911 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
912 | NLP_EVT_CMPL_PRLI); | ||
904 | } | 913 | } |
905 | 914 | ||
906 | out: | 915 | out: |
@@ -909,9 +918,11 @@ out: | |||
909 | } | 918 | } |
910 | 919 | ||
911 | int | 920 | int |
912 | lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | 921 | lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
913 | uint8_t retry) | 922 | uint8_t retry) |
914 | { | 923 | { |
924 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
925 | struct lpfc_hba *phba = vport->phba; | ||
915 | PRLI *npr; | 926 | PRLI *npr; |
916 | IOCB_t *icmd; | 927 | IOCB_t *icmd; |
917 | struct lpfc_iocbq *elsiocb; | 928 | struct lpfc_iocbq *elsiocb; |
@@ -924,8 +935,8 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
924 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 935 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
925 | 936 | ||
926 | cmdsize = (sizeof (uint32_t) + sizeof (PRLI)); | 937 | cmdsize = (sizeof (uint32_t) + sizeof (PRLI)); |
927 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, | 938 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, |
928 | ndlp->nlp_DID, ELS_CMD_PRLI); | 939 | ndlp->nlp_DID, ELS_CMD_PRLI); |
929 | if (!elsiocb) | 940 | if (!elsiocb) |
930 | return 1; | 941 | return 1; |
931 | 942 | ||
@@ -957,79 +968,80 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
957 | 968 | ||
958 | phba->fc_stat.elsXmitPRLI++; | 969 | phba->fc_stat.elsXmitPRLI++; |
959 | elsiocb->iocb_cmpl = lpfc_cmpl_els_prli; | 970 | elsiocb->iocb_cmpl = lpfc_cmpl_els_prli; |
960 | spin_lock_irq(phba->host->host_lock); | 971 | spin_lock_irq(shost->host_lock); |
961 | ndlp->nlp_flag |= NLP_PRLI_SND; | 972 | ndlp->nlp_flag |= NLP_PRLI_SND; |
973 | spin_unlock_irq(shost->host_lock); | ||
962 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 974 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
975 | spin_lock_irq(shost->host_lock); | ||
963 | ndlp->nlp_flag &= ~NLP_PRLI_SND; | 976 | ndlp->nlp_flag &= ~NLP_PRLI_SND; |
964 | spin_unlock_irq(phba->host->host_lock); | 977 | spin_unlock_irq(shost->host_lock); |
965 | lpfc_els_free_iocb(phba, elsiocb); | 978 | lpfc_els_free_iocb(phba, elsiocb); |
966 | return 1; | 979 | return 1; |
967 | } | 980 | } |
968 | spin_unlock_irq(phba->host->host_lock); | 981 | vport->fc_prli_sent++; |
969 | phba->fc_prli_sent++; | ||
970 | return 0; | 982 | return 0; |
971 | } | 983 | } |
972 | 984 | ||
973 | static void | 985 | static void |
974 | lpfc_more_adisc(struct lpfc_hba * phba) | 986 | lpfc_more_adisc(struct lpfc_vport *vport) |
975 | { | 987 | { |
976 | int sentadisc; | 988 | int sentadisc; |
989 | struct lpfc_hba *phba = vport->phba; | ||
977 | 990 | ||
978 | if (phba->num_disc_nodes) | 991 | if (vport->num_disc_nodes) |
979 | phba->num_disc_nodes--; | 992 | vport->num_disc_nodes--; |
980 | 993 | ||
981 | /* Continue discovery with <num_disc_nodes> ADISCs to go */ | 994 | /* Continue discovery with <num_disc_nodes> ADISCs to go */ |
982 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 995 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
983 | "%d:0210 Continue discovery with %d ADISCs to go " | 996 | "%d:0210 Continue discovery with %d ADISCs to go " |
984 | "Data: x%x x%x x%x\n", | 997 | "Data: x%x x%x x%x\n", |
985 | phba->brd_no, phba->num_disc_nodes, phba->fc_adisc_cnt, | 998 | phba->brd_no, vport->num_disc_nodes, |
986 | phba->fc_flag, phba->hba_state); | 999 | vport->fc_adisc_cnt, vport->fc_flag, vport->port_state); |
987 | 1000 | ||
988 | /* Check to see if there are more ADISCs to be sent */ | 1001 | /* Check to see if there are more ADISCs to be sent */ |
989 | if (phba->fc_flag & FC_NLP_MORE) { | 1002 | if (vport->fc_flag & FC_NLP_MORE) { |
990 | lpfc_set_disctmo(phba); | 1003 | lpfc_set_disctmo(vport); |
991 | 1004 | /* go thru NPR nodes and issue any remaining ELS ADISCs */ | |
992 | /* go thru NPR list and issue any remaining ELS ADISCs */ | 1005 | sentadisc = lpfc_els_disc_adisc(vport); |
993 | sentadisc = lpfc_els_disc_adisc(phba); | ||
994 | } | 1006 | } |
995 | return; | 1007 | return; |
996 | } | 1008 | } |
997 | 1009 | ||
998 | static void | 1010 | static void |
999 | lpfc_rscn_disc(struct lpfc_hba * phba) | 1011 | lpfc_rscn_disc(struct lpfc_vport *vport) |
1000 | { | 1012 | { |
1013 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1014 | |||
1001 | /* RSCN discovery */ | 1015 | /* RSCN discovery */ |
1002 | /* go thru NPR list and issue ELS PLOGIs */ | 1016 | /* go thru NPR nodes and issue ELS PLOGIs */ |
1003 | if (phba->fc_npr_cnt) { | 1017 | if (vport->fc_npr_cnt) |
1004 | if (lpfc_els_disc_plogi(phba)) | 1018 | if (lpfc_els_disc_plogi(vport)) |
1005 | return; | 1019 | return; |
1006 | } | 1020 | |
1007 | if (phba->fc_flag & FC_RSCN_MODE) { | 1021 | if (vport->fc_flag & FC_RSCN_MODE) { |
1008 | /* Check to see if more RSCNs came in while we were | 1022 | /* Check to see if more RSCNs came in while we were |
1009 | * processing this one. | 1023 | * processing this one. |
1010 | */ | 1024 | */ |
1011 | if ((phba->fc_rscn_id_cnt == 0) && | 1025 | if ((vport->fc_rscn_id_cnt == 0) && |
1012 | (!(phba->fc_flag & FC_RSCN_DISCOVERY))) { | 1026 | (!(vport->fc_flag & FC_RSCN_DISCOVERY))) { |
1013 | spin_lock_irq(phba->host->host_lock); | 1027 | spin_lock_irq(shost->host_lock); |
1014 | phba->fc_flag &= ~FC_RSCN_MODE; | 1028 | vport->fc_flag &= ~FC_RSCN_MODE; |
1015 | spin_unlock_irq(phba->host->host_lock); | 1029 | spin_unlock_irq(shost->host_lock); |
1016 | } else { | 1030 | } else { |
1017 | lpfc_els_handle_rscn(phba); | 1031 | lpfc_els_handle_rscn(vport); |
1018 | } | 1032 | } |
1019 | } | 1033 | } |
1020 | } | 1034 | } |
1021 | 1035 | ||
1022 | static void | 1036 | static void |
1023 | lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 1037 | lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1024 | struct lpfc_iocbq * rspiocb) | 1038 | struct lpfc_iocbq *rspiocb) |
1025 | { | 1039 | { |
1040 | struct lpfc_vport *vport = cmdiocb->vport; | ||
1041 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1026 | IOCB_t *irsp; | 1042 | IOCB_t *irsp; |
1027 | struct lpfc_sli *psli; | ||
1028 | struct lpfc_nodelist *ndlp; | 1043 | struct lpfc_nodelist *ndlp; |
1029 | LPFC_MBOXQ_t *mbox; | 1044 | int disc; |
1030 | int disc, rc; | ||
1031 | |||
1032 | psli = &phba->sli; | ||
1033 | 1045 | ||
1034 | /* we pass cmdiocb to state machine which needs rspiocb as well */ | 1046 | /* we pass cmdiocb to state machine which needs rspiocb as well */ |
1035 | cmdiocb->context_un.rsp_iocb = rspiocb; | 1047 | cmdiocb->context_un.rsp_iocb = rspiocb; |
@@ -1040,10 +1052,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1040 | /* Since ndlp can be freed in the disc state machine, note if this node | 1052 | /* Since ndlp can be freed in the disc state machine, note if this node |
1041 | * is being used during discovery. | 1053 | * is being used during discovery. |
1042 | */ | 1054 | */ |
1055 | spin_lock_irq(shost->host_lock); | ||
1043 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); | 1056 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); |
1044 | spin_lock_irq(phba->host->host_lock); | ||
1045 | ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC); | 1057 | ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC); |
1046 | spin_unlock_irq(phba->host->host_lock); | 1058 | spin_unlock_irq(shost->host_lock); |
1047 | 1059 | ||
1048 | /* ADISC completes to NPort <nlp_DID> */ | 1060 | /* ADISC completes to NPort <nlp_DID> */ |
1049 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1061 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -1051,13 +1063,13 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1051 | "Data: x%x x%x x%x x%x x%x\n", | 1063 | "Data: x%x x%x x%x x%x x%x\n", |
1052 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, | 1064 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, |
1053 | irsp->un.ulpWord[4], irsp->ulpTimeout, disc, | 1065 | irsp->un.ulpWord[4], irsp->ulpTimeout, disc, |
1054 | phba->num_disc_nodes); | 1066 | vport->num_disc_nodes); |
1055 | 1067 | ||
1056 | /* Check to see if link went down during discovery */ | 1068 | /* Check to see if link went down during discovery */ |
1057 | if (lpfc_els_chk_latt(phba)) { | 1069 | if (lpfc_els_chk_latt(vport)) { |
1058 | spin_lock_irq(phba->host->host_lock); | 1070 | spin_lock_irq(shost->host_lock); |
1059 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1071 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
1060 | spin_unlock_irq(phba->host->host_lock); | 1072 | spin_unlock_irq(shost->host_lock); |
1061 | goto out; | 1073 | goto out; |
1062 | } | 1074 | } |
1063 | 1075 | ||
@@ -1066,10 +1078,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1066 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) { | 1078 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) { |
1067 | /* ELS command is being retried */ | 1079 | /* ELS command is being retried */ |
1068 | if (disc) { | 1080 | if (disc) { |
1069 | spin_lock_irq(phba->host->host_lock); | 1081 | spin_lock_irq(shost->host_lock); |
1070 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1082 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
1071 | spin_unlock_irq(phba->host->host_lock); | 1083 | spin_unlock_irq(shost->host_lock); |
1072 | lpfc_set_disctmo(phba); | 1084 | lpfc_set_disctmo(vport); |
1073 | } | 1085 | } |
1074 | goto out; | 1086 | goto out; |
1075 | } | 1087 | } |
@@ -1079,54 +1091,30 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1079 | ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) && | 1091 | ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) && |
1080 | (irsp->un.ulpWord[4] != IOERR_LINK_DOWN) && | 1092 | (irsp->un.ulpWord[4] != IOERR_LINK_DOWN) && |
1081 | (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) { | 1093 | (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) { |
1082 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 1094 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1083 | NLP_EVT_CMPL_ADISC); | 1095 | NLP_EVT_CMPL_ADISC); |
1084 | } | 1096 | } |
1085 | } else { | 1097 | } else { |
1086 | /* Good status, call state machine */ | 1098 | /* Good status, call state machine */ |
1087 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 1099 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1088 | NLP_EVT_CMPL_ADISC); | 1100 | NLP_EVT_CMPL_ADISC); |
1089 | } | 1101 | } |
1090 | 1102 | ||
1091 | if (disc && phba->num_disc_nodes) { | 1103 | if (disc && vport->num_disc_nodes) { |
1092 | /* Check to see if there are more ADISCs to be sent */ | 1104 | /* Check to see if there are more ADISCs to be sent */ |
1093 | lpfc_more_adisc(phba); | 1105 | lpfc_more_adisc(vport); |
1094 | 1106 | ||
1095 | /* Check to see if we are done with ADISC authentication */ | 1107 | /* Check to see if we are done with ADISC authentication */ |
1096 | if (phba->num_disc_nodes == 0) { | 1108 | if (vport->num_disc_nodes == 0) { |
1097 | lpfc_can_disctmo(phba); | 1109 | lpfc_can_disctmo(vport); |
1098 | /* If we get here, there is nothing left to wait for */ | 1110 | /* If we get here, there is nothing left to wait for */ |
1099 | if ((phba->hba_state < LPFC_HBA_READY) && | 1111 | if (vport->port_state < LPFC_VPORT_READY && |
1100 | (phba->hba_state != LPFC_CLEAR_LA)) { | 1112 | phba->link_state != LPFC_CLEAR_LA) { |
1101 | /* Link up discovery */ | 1113 | if (vport->port_type == LPFC_PHYSICAL_PORT) { |
1102 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, | 1114 | lpfc_issue_clear_la(phba, vport); |
1103 | GFP_KERNEL))) { | ||
1104 | phba->hba_state = LPFC_CLEAR_LA; | ||
1105 | lpfc_clear_la(phba, mbox); | ||
1106 | mbox->mbox_cmpl = | ||
1107 | lpfc_mbx_cmpl_clear_la; | ||
1108 | rc = lpfc_sli_issue_mbox | ||
1109 | (phba, mbox, | ||
1110 | (MBX_NOWAIT | MBX_STOP_IOCB)); | ||
1111 | if (rc == MBX_NOT_FINISHED) { | ||
1112 | mempool_free(mbox, | ||
1113 | phba->mbox_mem_pool); | ||
1114 | lpfc_disc_flush_list(phba); | ||
1115 | psli->ring[(psli->extra_ring)]. | ||
1116 | flag &= | ||
1117 | ~LPFC_STOP_IOCB_EVENT; | ||
1118 | psli->ring[(psli->fcp_ring)]. | ||
1119 | flag &= | ||
1120 | ~LPFC_STOP_IOCB_EVENT; | ||
1121 | psli->ring[(psli->next_ring)]. | ||
1122 | flag &= | ||
1123 | ~LPFC_STOP_IOCB_EVENT; | ||
1124 | phba->hba_state = | ||
1125 | LPFC_HBA_READY; | ||
1126 | } | ||
1127 | } | 1115 | } |
1128 | } else { | 1116 | } else { |
1129 | lpfc_rscn_disc(phba); | 1117 | lpfc_rscn_disc(vport); |
1130 | } | 1118 | } |
1131 | } | 1119 | } |
1132 | } | 1120 | } |
@@ -1136,23 +1124,22 @@ out: | |||
1136 | } | 1124 | } |
1137 | 1125 | ||
1138 | int | 1126 | int |
1139 | lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | 1127 | lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1140 | uint8_t retry) | 1128 | uint8_t retry) |
1141 | { | 1129 | { |
1130 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1131 | struct lpfc_hba *phba = vport->phba; | ||
1142 | ADISC *ap; | 1132 | ADISC *ap; |
1143 | IOCB_t *icmd; | 1133 | IOCB_t *icmd; |
1144 | struct lpfc_iocbq *elsiocb; | 1134 | struct lpfc_iocbq *elsiocb; |
1145 | struct lpfc_sli_ring *pring; | 1135 | struct lpfc_sli *psli = &phba->sli; |
1146 | struct lpfc_sli *psli; | 1136 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; |
1147 | uint8_t *pcmd; | 1137 | uint8_t *pcmd; |
1148 | uint16_t cmdsize; | 1138 | uint16_t cmdsize; |
1149 | 1139 | ||
1150 | psli = &phba->sli; | ||
1151 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | ||
1152 | |||
1153 | cmdsize = (sizeof (uint32_t) + sizeof (ADISC)); | 1140 | cmdsize = (sizeof (uint32_t) + sizeof (ADISC)); |
1154 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, | 1141 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, |
1155 | ndlp->nlp_DID, ELS_CMD_ADISC); | 1142 | ndlp->nlp_DID, ELS_CMD_ADISC); |
1156 | if (!elsiocb) | 1143 | if (!elsiocb) |
1157 | return 1; | 1144 | return 1; |
1158 | 1145 | ||
@@ -1166,41 +1153,43 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
1166 | /* Fill in ADISC payload */ | 1153 | /* Fill in ADISC payload */ |
1167 | ap = (ADISC *) pcmd; | 1154 | ap = (ADISC *) pcmd; |
1168 | ap->hardAL_PA = phba->fc_pref_ALPA; | 1155 | ap->hardAL_PA = phba->fc_pref_ALPA; |
1169 | memcpy(&ap->portName, &phba->fc_portname, sizeof (struct lpfc_name)); | 1156 | memcpy(&ap->portName, &vport->fc_portname, sizeof (struct lpfc_name)); |
1170 | memcpy(&ap->nodeName, &phba->fc_nodename, sizeof (struct lpfc_name)); | 1157 | memcpy(&ap->nodeName, &vport->fc_nodename, sizeof (struct lpfc_name)); |
1171 | ap->DID = be32_to_cpu(phba->fc_myDID); | 1158 | ap->DID = be32_to_cpu(vport->fc_myDID); |
1172 | 1159 | ||
1173 | phba->fc_stat.elsXmitADISC++; | 1160 | phba->fc_stat.elsXmitADISC++; |
1174 | elsiocb->iocb_cmpl = lpfc_cmpl_els_adisc; | 1161 | elsiocb->iocb_cmpl = lpfc_cmpl_els_adisc; |
1175 | spin_lock_irq(phba->host->host_lock); | 1162 | spin_lock_irq(shost->host_lock); |
1176 | ndlp->nlp_flag |= NLP_ADISC_SND; | 1163 | ndlp->nlp_flag |= NLP_ADISC_SND; |
1164 | spin_unlock_irq(shost->host_lock); | ||
1177 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1165 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
1166 | spin_lock_irq(shost->host_lock); | ||
1178 | ndlp->nlp_flag &= ~NLP_ADISC_SND; | 1167 | ndlp->nlp_flag &= ~NLP_ADISC_SND; |
1179 | spin_unlock_irq(phba->host->host_lock); | 1168 | spin_unlock_irq(shost->host_lock); |
1180 | lpfc_els_free_iocb(phba, elsiocb); | 1169 | lpfc_els_free_iocb(phba, elsiocb); |
1181 | return 1; | 1170 | return 1; |
1182 | } | 1171 | } |
1183 | spin_unlock_irq(phba->host->host_lock); | ||
1184 | return 0; | 1172 | return 0; |
1185 | } | 1173 | } |
1186 | 1174 | ||
1187 | static void | 1175 | static void |
1188 | lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 1176 | lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1189 | struct lpfc_iocbq * rspiocb) | 1177 | struct lpfc_iocbq *rspiocb) |
1190 | { | 1178 | { |
1179 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | ||
1180 | struct lpfc_vport *vport = ndlp->vport; | ||
1181 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1191 | IOCB_t *irsp; | 1182 | IOCB_t *irsp; |
1192 | struct lpfc_sli *psli; | 1183 | struct lpfc_sli *psli; |
1193 | struct lpfc_nodelist *ndlp; | ||
1194 | 1184 | ||
1195 | psli = &phba->sli; | 1185 | psli = &phba->sli; |
1196 | /* we pass cmdiocb to state machine which needs rspiocb as well */ | 1186 | /* we pass cmdiocb to state machine which needs rspiocb as well */ |
1197 | cmdiocb->context_un.rsp_iocb = rspiocb; | 1187 | cmdiocb->context_un.rsp_iocb = rspiocb; |
1198 | 1188 | ||
1199 | irsp = &(rspiocb->iocb); | 1189 | irsp = &(rspiocb->iocb); |
1200 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 1190 | spin_lock_irq(shost->host_lock); |
1201 | spin_lock_irq(phba->host->host_lock); | ||
1202 | ndlp->nlp_flag &= ~NLP_LOGO_SND; | 1191 | ndlp->nlp_flag &= ~NLP_LOGO_SND; |
1203 | spin_unlock_irq(phba->host->host_lock); | 1192 | spin_unlock_irq(shost->host_lock); |
1204 | 1193 | ||
1205 | /* LOGO completes to NPort <nlp_DID> */ | 1194 | /* LOGO completes to NPort <nlp_DID> */ |
1206 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1195 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -1208,18 +1197,17 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1208 | "Data: x%x x%x x%x x%x\n", | 1197 | "Data: x%x x%x x%x x%x\n", |
1209 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, | 1198 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, |
1210 | irsp->un.ulpWord[4], irsp->ulpTimeout, | 1199 | irsp->un.ulpWord[4], irsp->ulpTimeout, |
1211 | phba->num_disc_nodes); | 1200 | vport->num_disc_nodes); |
1212 | 1201 | ||
1213 | /* Check to see if link went down during discovery */ | 1202 | /* Check to see if link went down during discovery */ |
1214 | if (lpfc_els_chk_latt(phba)) | 1203 | if (lpfc_els_chk_latt(vport)) |
1215 | goto out; | 1204 | goto out; |
1216 | 1205 | ||
1217 | if (irsp->ulpStatus) { | 1206 | if (irsp->ulpStatus) { |
1218 | /* Check for retry */ | 1207 | /* Check for retry */ |
1219 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) { | 1208 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) |
1220 | /* ELS command is being retried */ | 1209 | /* ELS command is being retried */ |
1221 | goto out; | 1210 | goto out; |
1222 | } | ||
1223 | /* LOGO failed */ | 1211 | /* LOGO failed */ |
1224 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1212 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1225 | if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && | 1213 | if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && |
@@ -1228,14 +1216,15 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1228 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { | 1216 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { |
1229 | goto out; | 1217 | goto out; |
1230 | } else { | 1218 | } else { |
1231 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 1219 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1232 | NLP_EVT_CMPL_LOGO); | 1220 | NLP_EVT_CMPL_LOGO); |
1233 | } | 1221 | } |
1234 | } else { | 1222 | } else { |
1235 | /* Good status, call state machine. | 1223 | /* Good status, call state machine. |
1236 | * This will unregister the rpi if needed. | 1224 | * This will unregister the rpi if needed. |
1237 | */ | 1225 | */ |
1238 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); | 1226 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1227 | NLP_EVT_CMPL_LOGO); | ||
1239 | } | 1228 | } |
1240 | 1229 | ||
1241 | out: | 1230 | out: |
@@ -1244,9 +1233,11 @@ out: | |||
1244 | } | 1233 | } |
1245 | 1234 | ||
1246 | int | 1235 | int |
1247 | lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | 1236 | lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1248 | uint8_t retry) | 1237 | uint8_t retry) |
1249 | { | 1238 | { |
1239 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1240 | struct lpfc_hba *phba = vport->phba; | ||
1250 | IOCB_t *icmd; | 1241 | IOCB_t *icmd; |
1251 | struct lpfc_iocbq *elsiocb; | 1242 | struct lpfc_iocbq *elsiocb; |
1252 | struct lpfc_sli_ring *pring; | 1243 | struct lpfc_sli_ring *pring; |
@@ -1258,8 +1249,8 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
1258 | pring = &psli->ring[LPFC_ELS_RING]; | 1249 | pring = &psli->ring[LPFC_ELS_RING]; |
1259 | 1250 | ||
1260 | cmdsize = (2 * sizeof (uint32_t)) + sizeof (struct lpfc_name); | 1251 | cmdsize = (2 * sizeof (uint32_t)) + sizeof (struct lpfc_name); |
1261 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, | 1252 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, |
1262 | ndlp->nlp_DID, ELS_CMD_LOGO); | 1253 | ndlp->nlp_DID, ELS_CMD_LOGO); |
1263 | if (!elsiocb) | 1254 | if (!elsiocb) |
1264 | return 1; | 1255 | return 1; |
1265 | 1256 | ||
@@ -1269,28 +1260,30 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
1269 | pcmd += sizeof (uint32_t); | 1260 | pcmd += sizeof (uint32_t); |
1270 | 1261 | ||
1271 | /* Fill in LOGO payload */ | 1262 | /* Fill in LOGO payload */ |
1272 | *((uint32_t *) (pcmd)) = be32_to_cpu(phba->fc_myDID); | 1263 | *((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID); |
1273 | pcmd += sizeof (uint32_t); | 1264 | pcmd += sizeof (uint32_t); |
1274 | memcpy(pcmd, &phba->fc_portname, sizeof (struct lpfc_name)); | 1265 | memcpy(pcmd, &vport->fc_portname, sizeof (struct lpfc_name)); |
1275 | 1266 | ||
1276 | phba->fc_stat.elsXmitLOGO++; | 1267 | phba->fc_stat.elsXmitLOGO++; |
1277 | elsiocb->iocb_cmpl = lpfc_cmpl_els_logo; | 1268 | elsiocb->iocb_cmpl = lpfc_cmpl_els_logo; |
1278 | spin_lock_irq(phba->host->host_lock); | 1269 | spin_lock_irq(shost->host_lock); |
1279 | ndlp->nlp_flag |= NLP_LOGO_SND; | 1270 | ndlp->nlp_flag |= NLP_LOGO_SND; |
1271 | spin_unlock_irq(shost->host_lock); | ||
1280 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1272 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
1273 | spin_lock_irq(shost->host_lock); | ||
1281 | ndlp->nlp_flag &= ~NLP_LOGO_SND; | 1274 | ndlp->nlp_flag &= ~NLP_LOGO_SND; |
1282 | spin_unlock_irq(phba->host->host_lock); | 1275 | spin_unlock_irq(shost->host_lock); |
1283 | lpfc_els_free_iocb(phba, elsiocb); | 1276 | lpfc_els_free_iocb(phba, elsiocb); |
1284 | return 1; | 1277 | return 1; |
1285 | } | 1278 | } |
1286 | spin_unlock_irq(phba->host->host_lock); | ||
1287 | return 0; | 1279 | return 0; |
1288 | } | 1280 | } |
1289 | 1281 | ||
1290 | static void | 1282 | static void |
1291 | lpfc_cmpl_els_cmd(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 1283 | lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1292 | struct lpfc_iocbq * rspiocb) | 1284 | struct lpfc_iocbq *rspiocb) |
1293 | { | 1285 | { |
1286 | struct lpfc_vport *vport = cmdiocb->vport; | ||
1294 | IOCB_t *irsp; | 1287 | IOCB_t *irsp; |
1295 | 1288 | ||
1296 | irsp = &rspiocb->iocb; | 1289 | irsp = &rspiocb->iocb; |
@@ -1305,14 +1298,15 @@ lpfc_cmpl_els_cmd(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1305 | irsp->un.ulpWord[4], irsp->ulpTimeout); | 1298 | irsp->un.ulpWord[4], irsp->ulpTimeout); |
1306 | 1299 | ||
1307 | /* Check to see if link went down during discovery */ | 1300 | /* Check to see if link went down during discovery */ |
1308 | lpfc_els_chk_latt(phba); | 1301 | lpfc_els_chk_latt(vport); |
1309 | lpfc_els_free_iocb(phba, cmdiocb); | 1302 | lpfc_els_free_iocb(phba, cmdiocb); |
1310 | return; | 1303 | return; |
1311 | } | 1304 | } |
1312 | 1305 | ||
1313 | int | 1306 | int |
1314 | lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | 1307 | lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) |
1315 | { | 1308 | { |
1309 | struct lpfc_hba *phba = vport->phba; | ||
1316 | IOCB_t *icmd; | 1310 | IOCB_t *icmd; |
1317 | struct lpfc_iocbq *elsiocb; | 1311 | struct lpfc_iocbq *elsiocb; |
1318 | struct lpfc_sli_ring *pring; | 1312 | struct lpfc_sli_ring *pring; |
@@ -1328,10 +1322,11 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1328 | if (!ndlp) | 1322 | if (!ndlp) |
1329 | return 1; | 1323 | return 1; |
1330 | 1324 | ||
1331 | lpfc_nlp_init(phba, ndlp, nportid); | 1325 | lpfc_nlp_init(vport, ndlp, nportid); |
1326 | |||
1327 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, | ||
1328 | ndlp->nlp_DID, ELS_CMD_SCR); | ||
1332 | 1329 | ||
1333 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, | ||
1334 | ndlp->nlp_DID, ELS_CMD_SCR); | ||
1335 | if (!elsiocb) { | 1330 | if (!elsiocb) { |
1336 | lpfc_nlp_put(ndlp); | 1331 | lpfc_nlp_put(ndlp); |
1337 | return 1; | 1332 | return 1; |
@@ -1349,21 +1344,19 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1349 | 1344 | ||
1350 | phba->fc_stat.elsXmitSCR++; | 1345 | phba->fc_stat.elsXmitSCR++; |
1351 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; | 1346 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; |
1352 | spin_lock_irq(phba->host->host_lock); | ||
1353 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1347 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
1354 | spin_unlock_irq(phba->host->host_lock); | ||
1355 | lpfc_nlp_put(ndlp); | 1348 | lpfc_nlp_put(ndlp); |
1356 | lpfc_els_free_iocb(phba, elsiocb); | 1349 | lpfc_els_free_iocb(phba, elsiocb); |
1357 | return 1; | 1350 | return 1; |
1358 | } | 1351 | } |
1359 | spin_unlock_irq(phba->host->host_lock); | ||
1360 | lpfc_nlp_put(ndlp); | 1352 | lpfc_nlp_put(ndlp); |
1361 | return 0; | 1353 | return 0; |
1362 | } | 1354 | } |
1363 | 1355 | ||
1364 | static int | 1356 | static int |
1365 | lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | 1357 | lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) |
1366 | { | 1358 | { |
1359 | struct lpfc_hba *phba = vport->phba; | ||
1367 | IOCB_t *icmd; | 1360 | IOCB_t *icmd; |
1368 | struct lpfc_iocbq *elsiocb; | 1361 | struct lpfc_iocbq *elsiocb; |
1369 | struct lpfc_sli_ring *pring; | 1362 | struct lpfc_sli_ring *pring; |
@@ -1381,10 +1374,11 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1381 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | 1374 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
1382 | if (!ndlp) | 1375 | if (!ndlp) |
1383 | return 1; | 1376 | return 1; |
1384 | lpfc_nlp_init(phba, ndlp, nportid); | ||
1385 | 1377 | ||
1386 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, | 1378 | lpfc_nlp_init(vport, ndlp, nportid); |
1387 | ndlp->nlp_DID, ELS_CMD_RNID); | 1379 | |
1380 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, | ||
1381 | ndlp->nlp_DID, ELS_CMD_RNID); | ||
1388 | if (!elsiocb) { | 1382 | if (!elsiocb) { |
1389 | lpfc_nlp_put(ndlp); | 1383 | lpfc_nlp_put(ndlp); |
1390 | return 1; | 1384 | return 1; |
@@ -1401,13 +1395,14 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1401 | memset(fp, 0, sizeof (FARP)); | 1395 | memset(fp, 0, sizeof (FARP)); |
1402 | lp = (uint32_t *) pcmd; | 1396 | lp = (uint32_t *) pcmd; |
1403 | *lp++ = be32_to_cpu(nportid); | 1397 | *lp++ = be32_to_cpu(nportid); |
1404 | *lp++ = be32_to_cpu(phba->fc_myDID); | 1398 | *lp++ = be32_to_cpu(vport->fc_myDID); |
1405 | fp->Rflags = 0; | 1399 | fp->Rflags = 0; |
1406 | fp->Mflags = (FARP_MATCH_PORT | FARP_MATCH_NODE); | 1400 | fp->Mflags = (FARP_MATCH_PORT | FARP_MATCH_NODE); |
1407 | 1401 | ||
1408 | memcpy(&fp->RportName, &phba->fc_portname, sizeof (struct lpfc_name)); | 1402 | memcpy(&fp->RportName, &vport->fc_portname, sizeof (struct lpfc_name)); |
1409 | memcpy(&fp->RnodeName, &phba->fc_nodename, sizeof (struct lpfc_name)); | 1403 | memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof (struct lpfc_name)); |
1410 | if ((ondlp = lpfc_findnode_did(phba, nportid))) { | 1404 | ondlp = lpfc_findnode_did(vport, nportid); |
1405 | if (ondlp) { | ||
1411 | memcpy(&fp->OportName, &ondlp->nlp_portname, | 1406 | memcpy(&fp->OportName, &ondlp->nlp_portname, |
1412 | sizeof (struct lpfc_name)); | 1407 | sizeof (struct lpfc_name)); |
1413 | memcpy(&fp->OnodeName, &ondlp->nlp_nodename, | 1408 | memcpy(&fp->OnodeName, &ondlp->nlp_nodename, |
@@ -1416,22 +1411,23 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1416 | 1411 | ||
1417 | phba->fc_stat.elsXmitFARPR++; | 1412 | phba->fc_stat.elsXmitFARPR++; |
1418 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; | 1413 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; |
1419 | spin_lock_irq(phba->host->host_lock); | ||
1420 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1414 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
1421 | spin_unlock_irq(phba->host->host_lock); | ||
1422 | lpfc_nlp_put(ndlp); | 1415 | lpfc_nlp_put(ndlp); |
1423 | lpfc_els_free_iocb(phba, elsiocb); | 1416 | lpfc_els_free_iocb(phba, elsiocb); |
1424 | return 1; | 1417 | return 1; |
1425 | } | 1418 | } |
1426 | spin_unlock_irq(phba->host->host_lock); | ||
1427 | lpfc_nlp_put(ndlp); | 1419 | lpfc_nlp_put(ndlp); |
1428 | return 0; | 1420 | return 0; |
1429 | } | 1421 | } |
1430 | 1422 | ||
1431 | void | 1423 | void |
1432 | lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp) | 1424 | lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) |
1433 | { | 1425 | { |
1426 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1427 | |||
1428 | spin_lock_irq(shost->host_lock); | ||
1434 | nlp->nlp_flag &= ~NLP_DELAY_TMO; | 1429 | nlp->nlp_flag &= ~NLP_DELAY_TMO; |
1430 | spin_unlock_irq(shost->host_lock); | ||
1435 | del_timer_sync(&nlp->nlp_delayfunc); | 1431 | del_timer_sync(&nlp->nlp_delayfunc); |
1436 | nlp->nlp_last_elscmd = 0; | 1432 | nlp->nlp_last_elscmd = 0; |
1437 | 1433 | ||
@@ -1439,28 +1435,36 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp) | |||
1439 | list_del_init(&nlp->els_retry_evt.evt_listp); | 1435 | list_del_init(&nlp->els_retry_evt.evt_listp); |
1440 | 1436 | ||
1441 | if (nlp->nlp_flag & NLP_NPR_2B_DISC) { | 1437 | if (nlp->nlp_flag & NLP_NPR_2B_DISC) { |
1438 | spin_lock_irq(shost->host_lock); | ||
1442 | nlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1439 | nlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1443 | if (phba->num_disc_nodes) { | 1440 | spin_unlock_irq(shost->host_lock); |
1441 | if (vport->num_disc_nodes) { | ||
1444 | /* Check to see if there are more | 1442 | /* Check to see if there are more |
1445 | * PLOGIs to be sent | 1443 | * PLOGIs to be sent |
1446 | */ | 1444 | */ |
1447 | lpfc_more_plogi(phba); | 1445 | lpfc_more_plogi(vport); |
1448 | 1446 | ||
1449 | if (phba->num_disc_nodes == 0) { | 1447 | if (vport->num_disc_nodes == 0) { |
1450 | phba->fc_flag &= ~FC_NDISC_ACTIVE; | 1448 | spin_lock_irq(shost->host_lock); |
1451 | lpfc_can_disctmo(phba); | 1449 | vport->fc_flag &= ~FC_NDISC_ACTIVE; |
1452 | if (phba->fc_flag & FC_RSCN_MODE) { | 1450 | spin_unlock_irq(shost->host_lock); |
1451 | lpfc_can_disctmo(vport); | ||
1452 | if (vport->fc_flag & FC_RSCN_MODE) { | ||
1453 | /* | 1453 | /* |
1454 | * Check to see if more RSCNs | 1454 | * Check to see if more RSCNs |
1455 | * came in while we were | 1455 | * came in while we were |
1456 | * processing this one. | 1456 | * processing this one. |
1457 | */ | 1457 | */ |
1458 | if((phba->fc_rscn_id_cnt==0) && | 1458 | if (!vport->fc_rscn_id_cnt && |
1459 | !(phba->fc_flag & FC_RSCN_DISCOVERY)) { | 1459 | !(vport->fc_flag & |
1460 | phba->fc_flag &= ~FC_RSCN_MODE; | 1460 | FC_RSCN_DISCOVERY)) { |
1461 | spin_lock_irq(shost->host_lock); | ||
1462 | vport->fc_flag &= ~FC_RSCN_MODE; | ||
1463 | spin_unlock_irq( | ||
1464 | shost->host_lock); | ||
1461 | } | 1465 | } |
1462 | else { | 1466 | else { |
1463 | lpfc_els_handle_rscn(phba); | 1467 | lpfc_els_handle_rscn(vport); |
1464 | } | 1468 | } |
1465 | } | 1469 | } |
1466 | } | 1470 | } |
@@ -1472,18 +1476,20 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp) | |||
1472 | void | 1476 | void |
1473 | lpfc_els_retry_delay(unsigned long ptr) | 1477 | lpfc_els_retry_delay(unsigned long ptr) |
1474 | { | 1478 | { |
1475 | struct lpfc_nodelist *ndlp; | 1479 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) ptr; |
1476 | struct lpfc_hba *phba; | 1480 | struct lpfc_vport *vport = ndlp->vport; |
1481 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1482 | struct lpfc_hba *phba = vport->phba; | ||
1477 | unsigned long iflag; | 1483 | unsigned long iflag; |
1478 | struct lpfc_work_evt *evtp; | 1484 | struct lpfc_work_evt *evtp = &ndlp->els_retry_evt; |
1479 | 1485 | ||
1480 | ndlp = (struct lpfc_nodelist *)ptr; | 1486 | ndlp = (struct lpfc_nodelist *) ptr; |
1481 | phba = ndlp->nlp_phba; | 1487 | phba = ndlp->vport->phba; |
1482 | evtp = &ndlp->els_retry_evt; | 1488 | evtp = &ndlp->els_retry_evt; |
1483 | 1489 | ||
1484 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1490 | spin_lock_irqsave(shost->host_lock, iflag); |
1485 | if (!list_empty(&evtp->evt_listp)) { | 1491 | if (!list_empty(&evtp->evt_listp)) { |
1486 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1492 | spin_unlock_irqrestore(shost->host_lock, iflag); |
1487 | return; | 1493 | return; |
1488 | } | 1494 | } |
1489 | 1495 | ||
@@ -1493,31 +1499,29 @@ lpfc_els_retry_delay(unsigned long ptr) | |||
1493 | if (phba->work_wait) | 1499 | if (phba->work_wait) |
1494 | wake_up(phba->work_wait); | 1500 | wake_up(phba->work_wait); |
1495 | 1501 | ||
1496 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1502 | spin_unlock_irqrestore(shost->host_lock, iflag); |
1497 | return; | 1503 | return; |
1498 | } | 1504 | } |
1499 | 1505 | ||
1500 | void | 1506 | void |
1501 | lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | 1507 | lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) |
1502 | { | 1508 | { |
1503 | struct lpfc_hba *phba; | 1509 | struct lpfc_vport *vport = ndlp->vport; |
1504 | uint32_t cmd; | 1510 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1505 | uint32_t did; | 1511 | uint32_t cmd, did, retry; |
1506 | uint8_t retry; | ||
1507 | 1512 | ||
1508 | phba = ndlp->nlp_phba; | 1513 | spin_lock_irq(shost->host_lock); |
1509 | spin_lock_irq(phba->host->host_lock); | ||
1510 | did = ndlp->nlp_DID; | 1514 | did = ndlp->nlp_DID; |
1511 | cmd = ndlp->nlp_last_elscmd; | 1515 | cmd = ndlp->nlp_last_elscmd; |
1512 | ndlp->nlp_last_elscmd = 0; | 1516 | ndlp->nlp_last_elscmd = 0; |
1513 | 1517 | ||
1514 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1518 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1515 | spin_unlock_irq(phba->host->host_lock); | 1519 | spin_unlock_irq(shost->host_lock); |
1516 | return; | 1520 | return; |
1517 | } | 1521 | } |
1518 | 1522 | ||
1519 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 1523 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; |
1520 | spin_unlock_irq(phba->host->host_lock); | 1524 | spin_unlock_irq(shost->host_lock); |
1521 | /* | 1525 | /* |
1522 | * If a discovery event readded nlp_delayfunc after timer | 1526 | * If a discovery event readded nlp_delayfunc after timer |
1523 | * firing and before processing the timer, cancel the | 1527 | * firing and before processing the timer, cancel the |
@@ -1528,30 +1532,30 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | |||
1528 | 1532 | ||
1529 | switch (cmd) { | 1533 | switch (cmd) { |
1530 | case ELS_CMD_FLOGI: | 1534 | case ELS_CMD_FLOGI: |
1531 | lpfc_issue_els_flogi(phba, ndlp, retry); | 1535 | lpfc_issue_els_flogi(vport, ndlp, retry); |
1532 | break; | 1536 | break; |
1533 | case ELS_CMD_PLOGI: | 1537 | case ELS_CMD_PLOGI: |
1534 | if(!lpfc_issue_els_plogi(phba, ndlp->nlp_DID, retry)) { | 1538 | if (!lpfc_issue_els_plogi(vport, ndlp->nlp_DID, retry)) { |
1535 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1539 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1536 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 1540 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
1537 | } | 1541 | } |
1538 | break; | 1542 | break; |
1539 | case ELS_CMD_ADISC: | 1543 | case ELS_CMD_ADISC: |
1540 | if (!lpfc_issue_els_adisc(phba, ndlp, retry)) { | 1544 | if (!lpfc_issue_els_adisc(vport, ndlp, retry)) { |
1541 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1545 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1542 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); | 1546 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); |
1543 | } | 1547 | } |
1544 | break; | 1548 | break; |
1545 | case ELS_CMD_PRLI: | 1549 | case ELS_CMD_PRLI: |
1546 | if (!lpfc_issue_els_prli(phba, ndlp, retry)) { | 1550 | if (!lpfc_issue_els_prli(vport, ndlp, retry)) { |
1547 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1551 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1548 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PRLI_ISSUE); | 1552 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); |
1549 | } | 1553 | } |
1550 | break; | 1554 | break; |
1551 | case ELS_CMD_LOGO: | 1555 | case ELS_CMD_LOGO: |
1552 | if (!lpfc_issue_els_logo(phba, ndlp, retry)) { | 1556 | if (!lpfc_issue_els_logo(vport, ndlp, retry)) { |
1553 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1557 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1554 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1558 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1555 | } | 1559 | } |
1556 | break; | 1560 | break; |
1557 | } | 1561 | } |
@@ -1559,26 +1563,20 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | |||
1559 | } | 1563 | } |
1560 | 1564 | ||
1561 | static int | 1565 | static int |
1562 | lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 1566 | lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1563 | struct lpfc_iocbq * rspiocb) | 1567 | struct lpfc_iocbq *rspiocb) |
1564 | { | 1568 | { |
1565 | IOCB_t *irsp; | 1569 | struct lpfc_vport *vport = cmdiocb->vport; |
1566 | struct lpfc_dmabuf *pcmd; | 1570 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1567 | struct lpfc_nodelist *ndlp; | 1571 | IOCB_t *irsp = &rspiocb->iocb; |
1572 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | ||
1573 | struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
1568 | uint32_t *elscmd; | 1574 | uint32_t *elscmd; |
1569 | struct ls_rjt stat; | 1575 | struct ls_rjt stat; |
1570 | int retry, maxretry; | 1576 | int retry = 0, maxretry = lpfc_max_els_tries, delay = 0; |
1571 | int delay; | 1577 | uint32_t cmd = 0; |
1572 | uint32_t cmd; | ||
1573 | uint32_t did; | 1578 | uint32_t did; |
1574 | 1579 | ||
1575 | retry = 0; | ||
1576 | delay = 0; | ||
1577 | maxretry = lpfc_max_els_tries; | ||
1578 | irsp = &rspiocb->iocb; | ||
1579 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | ||
1580 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
1581 | cmd = 0; | ||
1582 | 1580 | ||
1583 | /* Note: context2 may be 0 for internal driver abort | 1581 | /* Note: context2 may be 0 for internal driver abort |
1584 | * of delays ELS command. | 1582 | * of delays ELS command. |
@@ -1594,7 +1592,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1594 | else { | 1592 | else { |
1595 | /* We should only hit this case for retrying PLOGI */ | 1593 | /* We should only hit this case for retrying PLOGI */ |
1596 | did = irsp->un.elsreq64.remoteID; | 1594 | did = irsp->un.elsreq64.remoteID; |
1597 | ndlp = lpfc_findnode_did(phba, did); | 1595 | ndlp = lpfc_findnode_did(vport, did); |
1598 | if (!ndlp && (cmd != ELS_CMD_PLOGI)) | 1596 | if (!ndlp && (cmd != ELS_CMD_PLOGI)) |
1599 | return 1; | 1597 | return 1; |
1600 | } | 1598 | } |
@@ -1607,11 +1605,8 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1607 | case IOSTAT_LOCAL_REJECT: | 1605 | case IOSTAT_LOCAL_REJECT: |
1608 | switch ((irsp->un.ulpWord[4] & 0xff)) { | 1606 | switch ((irsp->un.ulpWord[4] & 0xff)) { |
1609 | case IOERR_LOOP_OPEN_FAILURE: | 1607 | case IOERR_LOOP_OPEN_FAILURE: |
1610 | if (cmd == ELS_CMD_PLOGI) { | 1608 | if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0) |
1611 | if (cmdiocb->retry == 0) { | ||
1612 | delay = 1; | 1609 | delay = 1; |
1613 | } | ||
1614 | } | ||
1615 | retry = 1; | 1610 | retry = 1; |
1616 | break; | 1611 | break; |
1617 | 1612 | ||
@@ -1620,9 +1615,8 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1620 | break; | 1615 | break; |
1621 | 1616 | ||
1622 | case IOERR_NO_RESOURCES: | 1617 | case IOERR_NO_RESOURCES: |
1623 | if (cmd == ELS_CMD_PLOGI) { | 1618 | if (cmd == ELS_CMD_PLOGI) |
1624 | delay = 1; | 1619 | delay = 1; |
1625 | } | ||
1626 | retry = 1; | 1620 | retry = 1; |
1627 | break; | 1621 | break; |
1628 | 1622 | ||
@@ -1706,10 +1700,9 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1706 | 1700 | ||
1707 | if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) { | 1701 | if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) { |
1708 | /* If discovery / RSCN timer is running, reset it */ | 1702 | /* If discovery / RSCN timer is running, reset it */ |
1709 | if (timer_pending(&phba->fc_disctmo) || | 1703 | if (timer_pending(&vport->fc_disctmo) || |
1710 | (phba->fc_flag & FC_RSCN_MODE)) { | 1704 | (vport->fc_flag & FC_RSCN_MODE)) |
1711 | lpfc_set_disctmo(phba); | 1705 | lpfc_set_disctmo(vport); |
1712 | } | ||
1713 | } | 1706 | } |
1714 | 1707 | ||
1715 | phba->fc_stat.elsXmitRetry++; | 1708 | phba->fc_stat.elsXmitRetry++; |
@@ -1718,40 +1711,42 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1718 | ndlp->nlp_retry = cmdiocb->retry; | 1711 | ndlp->nlp_retry = cmdiocb->retry; |
1719 | 1712 | ||
1720 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 1713 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
1714 | spin_lock_irq(shost->host_lock); | ||
1721 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1715 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1716 | spin_unlock_irq(shost->host_lock); | ||
1722 | 1717 | ||
1723 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1718 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1724 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1719 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1725 | ndlp->nlp_last_elscmd = cmd; | 1720 | ndlp->nlp_last_elscmd = cmd; |
1726 | 1721 | ||
1727 | return 1; | 1722 | return 1; |
1728 | } | 1723 | } |
1729 | switch (cmd) { | 1724 | switch (cmd) { |
1730 | case ELS_CMD_FLOGI: | 1725 | case ELS_CMD_FLOGI: |
1731 | lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry); | 1726 | lpfc_issue_els_flogi(vport, ndlp, cmdiocb->retry); |
1732 | return 1; | 1727 | return 1; |
1733 | case ELS_CMD_PLOGI: | 1728 | case ELS_CMD_PLOGI: |
1734 | if (ndlp) { | 1729 | if (ndlp) { |
1735 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1730 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1736 | lpfc_nlp_set_state(phba, ndlp, | 1731 | lpfc_nlp_set_state(vport, ndlp, |
1737 | NLP_STE_PLOGI_ISSUE); | 1732 | NLP_STE_PLOGI_ISSUE); |
1738 | } | 1733 | } |
1739 | lpfc_issue_els_plogi(phba, did, cmdiocb->retry); | 1734 | lpfc_issue_els_plogi(vport, did, cmdiocb->retry); |
1740 | return 1; | 1735 | return 1; |
1741 | case ELS_CMD_ADISC: | 1736 | case ELS_CMD_ADISC: |
1742 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1737 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1743 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); | 1738 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); |
1744 | lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry); | 1739 | lpfc_issue_els_adisc(vport, ndlp, cmdiocb->retry); |
1745 | return 1; | 1740 | return 1; |
1746 | case ELS_CMD_PRLI: | 1741 | case ELS_CMD_PRLI: |
1747 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1742 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1748 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PRLI_ISSUE); | 1743 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); |
1749 | lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry); | 1744 | lpfc_issue_els_prli(vport, ndlp, cmdiocb->retry); |
1750 | return 1; | 1745 | return 1; |
1751 | case ELS_CMD_LOGO: | 1746 | case ELS_CMD_LOGO: |
1752 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1747 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1753 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1748 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1754 | lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry); | 1749 | lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry); |
1755 | return 1; | 1750 | return 1; |
1756 | } | 1751 | } |
1757 | } | 1752 | } |
@@ -1795,19 +1790,16 @@ lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) | |||
1795 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | 1790 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); |
1796 | kfree(buf_ptr); | 1791 | kfree(buf_ptr); |
1797 | } | 1792 | } |
1798 | spin_lock_irq(phba->host->host_lock); | ||
1799 | lpfc_sli_release_iocbq(phba, elsiocb); | 1793 | lpfc_sli_release_iocbq(phba, elsiocb); |
1800 | spin_unlock_irq(phba->host->host_lock); | ||
1801 | return 0; | 1794 | return 0; |
1802 | } | 1795 | } |
1803 | 1796 | ||
1804 | static void | 1797 | static void |
1805 | lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 1798 | lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1806 | struct lpfc_iocbq * rspiocb) | 1799 | struct lpfc_iocbq *rspiocb) |
1807 | { | 1800 | { |
1808 | struct lpfc_nodelist *ndlp; | 1801 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
1809 | 1802 | struct lpfc_vport *vport = cmdiocb->vport; | |
1810 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | ||
1811 | 1803 | ||
1812 | /* ACC to LOGO completes to NPort <nlp_DID> */ | 1804 | /* ACC to LOGO completes to NPort <nlp_DID> */ |
1813 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1805 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -1818,10 +1810,10 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1818 | 1810 | ||
1819 | switch (ndlp->nlp_state) { | 1811 | switch (ndlp->nlp_state) { |
1820 | case NLP_STE_UNUSED_NODE: /* node is just allocated */ | 1812 | case NLP_STE_UNUSED_NODE: /* node is just allocated */ |
1821 | lpfc_drop_node(phba, ndlp); | 1813 | lpfc_drop_node(vport, ndlp); |
1822 | break; | 1814 | break; |
1823 | case NLP_STE_NPR_NODE: /* NPort Recovery mode */ | 1815 | case NLP_STE_NPR_NODE: /* NPort Recovery mode */ |
1824 | lpfc_unreg_rpi(phba, ndlp); | 1816 | lpfc_unreg_rpi(vport, ndlp); |
1825 | break; | 1817 | break; |
1826 | default: | 1818 | default: |
1827 | break; | 1819 | break; |
@@ -1834,20 +1826,20 @@ static void | |||
1834 | lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 1826 | lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1835 | struct lpfc_iocbq *rspiocb) | 1827 | struct lpfc_iocbq *rspiocb) |
1836 | { | 1828 | { |
1829 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | ||
1830 | struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL; | ||
1831 | struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL; | ||
1837 | IOCB_t *irsp; | 1832 | IOCB_t *irsp; |
1838 | struct lpfc_nodelist *ndlp; | ||
1839 | LPFC_MBOXQ_t *mbox = NULL; | 1833 | LPFC_MBOXQ_t *mbox = NULL; |
1840 | struct lpfc_dmabuf *mp; | 1834 | struct lpfc_dmabuf *mp = NULL; |
1841 | 1835 | ||
1842 | irsp = &rspiocb->iocb; | 1836 | irsp = &rspiocb->iocb; |
1843 | 1837 | ||
1844 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | ||
1845 | if (cmdiocb->context_un.mbox) | 1838 | if (cmdiocb->context_un.mbox) |
1846 | mbox = cmdiocb->context_un.mbox; | 1839 | mbox = cmdiocb->context_un.mbox; |
1847 | 1840 | ||
1848 | |||
1849 | /* Check to see if link went down during discovery */ | 1841 | /* Check to see if link went down during discovery */ |
1850 | if (lpfc_els_chk_latt(phba) || !ndlp) { | 1842 | if (!ndlp || lpfc_els_chk_latt(vport)) { |
1851 | if (mbox) { | 1843 | if (mbox) { |
1852 | mp = (struct lpfc_dmabuf *) mbox->context1; | 1844 | mp = (struct lpfc_dmabuf *) mbox->context1; |
1853 | if (mp) { | 1845 | if (mp) { |
@@ -1866,17 +1858,19 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1866 | phba->brd_no, | 1858 | phba->brd_no, |
1867 | cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus, | 1859 | cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus, |
1868 | rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout, | 1860 | rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout, |
1869 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, | 1861 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, |
1870 | ndlp->nlp_rpi); | 1862 | ndlp->nlp_rpi); |
1871 | 1863 | ||
1872 | if (mbox) { | 1864 | if (mbox) { |
1873 | if ((rspiocb->iocb.ulpStatus == 0) | 1865 | if ((rspiocb->iocb.ulpStatus == 0) |
1874 | && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { | 1866 | && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { |
1875 | lpfc_unreg_rpi(phba, ndlp); | 1867 | lpfc_unreg_rpi(vport, ndlp); |
1876 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | 1868 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
1877 | mbox->context2 = lpfc_nlp_get(ndlp); | 1869 | mbox->context2 = lpfc_nlp_get(ndlp); |
1870 | mbox->vport = vport; | ||
1878 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1871 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1879 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE); | 1872 | lpfc_nlp_set_state(vport, ndlp, |
1873 | NLP_STE_REG_LOGIN_ISSUE); | ||
1880 | if (lpfc_sli_issue_mbox(phba, mbox, | 1874 | if (lpfc_sli_issue_mbox(phba, mbox, |
1881 | (MBX_NOWAIT | MBX_STOP_IOCB)) | 1875 | (MBX_NOWAIT | MBX_STOP_IOCB)) |
1882 | != MBX_NOT_FINISHED) { | 1876 | != MBX_NOT_FINISHED) { |
@@ -1892,7 +1886,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1892 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | 1886 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || |
1893 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN)))) { | 1887 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN)))) { |
1894 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | 1888 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { |
1895 | lpfc_drop_node(phba, ndlp); | 1889 | lpfc_drop_node(vport, ndlp); |
1896 | ndlp = NULL; | 1890 | ndlp = NULL; |
1897 | } | 1891 | } |
1898 | } | 1892 | } |
@@ -1906,19 +1900,21 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1906 | } | 1900 | } |
1907 | out: | 1901 | out: |
1908 | if (ndlp) { | 1902 | if (ndlp) { |
1909 | spin_lock_irq(phba->host->host_lock); | 1903 | spin_lock_irq(shost->host_lock); |
1910 | ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN; | 1904 | ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN; |
1911 | spin_unlock_irq(phba->host->host_lock); | 1905 | spin_unlock_irq(shost->host_lock); |
1912 | } | 1906 | } |
1913 | lpfc_els_free_iocb(phba, cmdiocb); | 1907 | lpfc_els_free_iocb(phba, cmdiocb); |
1914 | return; | 1908 | return; |
1915 | } | 1909 | } |
1916 | 1910 | ||
1917 | int | 1911 | int |
1918 | lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | 1912 | lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, |
1919 | struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp, | 1913 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp, |
1920 | LPFC_MBOXQ_t * mbox, uint8_t newnode) | 1914 | LPFC_MBOXQ_t *mbox, uint8_t newnode) |
1921 | { | 1915 | { |
1916 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1917 | struct lpfc_hba *phba = vport->phba; | ||
1922 | IOCB_t *icmd; | 1918 | IOCB_t *icmd; |
1923 | IOCB_t *oldcmd; | 1919 | IOCB_t *oldcmd; |
1924 | struct lpfc_iocbq *elsiocb; | 1920 | struct lpfc_iocbq *elsiocb; |
@@ -1936,12 +1932,15 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1936 | switch (flag) { | 1932 | switch (flag) { |
1937 | case ELS_CMD_ACC: | 1933 | case ELS_CMD_ACC: |
1938 | cmdsize = sizeof (uint32_t); | 1934 | cmdsize = sizeof (uint32_t); |
1939 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 1935 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, |
1940 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); | 1936 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
1941 | if (!elsiocb) { | 1937 | if (!elsiocb) { |
1938 | spin_lock_irq(shost->host_lock); | ||
1942 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; | 1939 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; |
1940 | spin_unlock_irq(shost->host_lock); | ||
1943 | return 1; | 1941 | return 1; |
1944 | } | 1942 | } |
1943 | |||
1945 | icmd = &elsiocb->iocb; | 1944 | icmd = &elsiocb->iocb; |
1946 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ | 1945 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ |
1947 | pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 1946 | pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -1950,8 +1949,8 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1950 | break; | 1949 | break; |
1951 | case ELS_CMD_PLOGI: | 1950 | case ELS_CMD_PLOGI: |
1952 | cmdsize = (sizeof (struct serv_parm) + sizeof (uint32_t)); | 1951 | cmdsize = (sizeof (struct serv_parm) + sizeof (uint32_t)); |
1953 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 1952 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, |
1954 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); | 1953 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
1955 | if (!elsiocb) | 1954 | if (!elsiocb) |
1956 | return 1; | 1955 | return 1; |
1957 | 1956 | ||
@@ -1964,11 +1963,11 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1964 | 1963 | ||
1965 | *((uint32_t *) (pcmd)) = ELS_CMD_ACC; | 1964 | *((uint32_t *) (pcmd)) = ELS_CMD_ACC; |
1966 | pcmd += sizeof (uint32_t); | 1965 | pcmd += sizeof (uint32_t); |
1967 | memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); | 1966 | memcpy(pcmd, &vport->fc_sparam, sizeof (struct serv_parm)); |
1968 | break; | 1967 | break; |
1969 | case ELS_CMD_PRLO: | 1968 | case ELS_CMD_PRLO: |
1970 | cmdsize = sizeof (uint32_t) + sizeof (PRLO); | 1969 | cmdsize = sizeof (uint32_t) + sizeof (PRLO); |
1971 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 1970 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, |
1972 | ndlp, ndlp->nlp_DID, ELS_CMD_PRLO); | 1971 | ndlp, ndlp->nlp_DID, ELS_CMD_PRLO); |
1973 | if (!elsiocb) | 1972 | if (!elsiocb) |
1974 | return 1; | 1973 | return 1; |
@@ -2001,18 +2000,16 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
2001 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); | 2000 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); |
2002 | 2001 | ||
2003 | if (ndlp->nlp_flag & NLP_LOGO_ACC) { | 2002 | if (ndlp->nlp_flag & NLP_LOGO_ACC) { |
2004 | spin_lock_irq(phba->host->host_lock); | 2003 | spin_lock_irq(shost->host_lock); |
2005 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; | 2004 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; |
2006 | spin_unlock_irq(phba->host->host_lock); | 2005 | spin_unlock_irq(shost->host_lock); |
2007 | elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc; | 2006 | elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc; |
2008 | } else { | 2007 | } else { |
2009 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2008 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; |
2010 | } | 2009 | } |
2011 | 2010 | ||
2012 | phba->fc_stat.elsXmitACC++; | 2011 | phba->fc_stat.elsXmitACC++; |
2013 | spin_lock_irq(phba->host->host_lock); | ||
2014 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 2012 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
2015 | spin_unlock_irq(phba->host->host_lock); | ||
2016 | if (rc == IOCB_ERROR) { | 2013 | if (rc == IOCB_ERROR) { |
2017 | lpfc_els_free_iocb(phba, elsiocb); | 2014 | lpfc_els_free_iocb(phba, elsiocb); |
2018 | return 1; | 2015 | return 1; |
@@ -2021,9 +2018,10 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
2021 | } | 2018 | } |
2022 | 2019 | ||
2023 | int | 2020 | int |
2024 | lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, | 2021 | lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, |
2025 | struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp) | 2022 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) |
2026 | { | 2023 | { |
2024 | struct lpfc_hba *phba = vport->phba; | ||
2027 | IOCB_t *icmd; | 2025 | IOCB_t *icmd; |
2028 | IOCB_t *oldcmd; | 2026 | IOCB_t *oldcmd; |
2029 | struct lpfc_iocbq *elsiocb; | 2027 | struct lpfc_iocbq *elsiocb; |
@@ -2037,8 +2035,8 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, | |||
2037 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 2035 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
2038 | 2036 | ||
2039 | cmdsize = 2 * sizeof (uint32_t); | 2037 | cmdsize = 2 * sizeof (uint32_t); |
2040 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 2038 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, |
2041 | ndlp, ndlp->nlp_DID, ELS_CMD_LS_RJT); | 2039 | ndlp->nlp_DID, ELS_CMD_LS_RJT); |
2042 | if (!elsiocb) | 2040 | if (!elsiocb) |
2043 | return 1; | 2041 | return 1; |
2044 | 2042 | ||
@@ -2061,9 +2059,7 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, | |||
2061 | 2059 | ||
2062 | phba->fc_stat.elsXmitLSRJT++; | 2060 | phba->fc_stat.elsXmitLSRJT++; |
2063 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2061 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; |
2064 | spin_lock_irq(phba->host->host_lock); | ||
2065 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 2062 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
2066 | spin_unlock_irq(phba->host->host_lock); | ||
2067 | if (rc == IOCB_ERROR) { | 2063 | if (rc == IOCB_ERROR) { |
2068 | lpfc_els_free_iocb(phba, elsiocb); | 2064 | lpfc_els_free_iocb(phba, elsiocb); |
2069 | return 1; | 2065 | return 1; |
@@ -2072,25 +2068,22 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, | |||
2072 | } | 2068 | } |
2073 | 2069 | ||
2074 | int | 2070 | int |
2075 | lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, | 2071 | lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, |
2076 | struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp) | 2072 | struct lpfc_nodelist *ndlp) |
2077 | { | 2073 | { |
2074 | struct lpfc_hba *phba = vport->phba; | ||
2075 | struct lpfc_sli *psli = &phba->sli; | ||
2076 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; | ||
2078 | ADISC *ap; | 2077 | ADISC *ap; |
2079 | IOCB_t *icmd; | 2078 | IOCB_t *icmd, *oldcmd; |
2080 | IOCB_t *oldcmd; | ||
2081 | struct lpfc_iocbq *elsiocb; | 2079 | struct lpfc_iocbq *elsiocb; |
2082 | struct lpfc_sli_ring *pring; | ||
2083 | struct lpfc_sli *psli; | ||
2084 | uint8_t *pcmd; | 2080 | uint8_t *pcmd; |
2085 | uint16_t cmdsize; | 2081 | uint16_t cmdsize; |
2086 | int rc; | 2082 | int rc; |
2087 | 2083 | ||
2088 | psli = &phba->sli; | ||
2089 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | ||
2090 | |||
2091 | cmdsize = sizeof (uint32_t) + sizeof (ADISC); | 2084 | cmdsize = sizeof (uint32_t) + sizeof (ADISC); |
2092 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 2085 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, |
2093 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); | 2086 | ndlp->nlp_DID, ELS_CMD_ACC); |
2094 | if (!elsiocb) | 2087 | if (!elsiocb) |
2095 | return 1; | 2088 | return 1; |
2096 | 2089 | ||
@@ -2113,15 +2106,13 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, | |||
2113 | 2106 | ||
2114 | ap = (ADISC *) (pcmd); | 2107 | ap = (ADISC *) (pcmd); |
2115 | ap->hardAL_PA = phba->fc_pref_ALPA; | 2108 | ap->hardAL_PA = phba->fc_pref_ALPA; |
2116 | memcpy(&ap->portName, &phba->fc_portname, sizeof (struct lpfc_name)); | 2109 | memcpy(&ap->portName, &vport->fc_portname, sizeof (struct lpfc_name)); |
2117 | memcpy(&ap->nodeName, &phba->fc_nodename, sizeof (struct lpfc_name)); | 2110 | memcpy(&ap->nodeName, &vport->fc_nodename, sizeof (struct lpfc_name)); |
2118 | ap->DID = be32_to_cpu(phba->fc_myDID); | 2111 | ap->DID = be32_to_cpu(vport->fc_myDID); |
2119 | 2112 | ||
2120 | phba->fc_stat.elsXmitACC++; | 2113 | phba->fc_stat.elsXmitACC++; |
2121 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2114 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; |
2122 | spin_lock_irq(phba->host->host_lock); | ||
2123 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 2115 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
2124 | spin_unlock_irq(phba->host->host_lock); | ||
2125 | if (rc == IOCB_ERROR) { | 2116 | if (rc == IOCB_ERROR) { |
2126 | lpfc_els_free_iocb(phba, elsiocb); | 2117 | lpfc_els_free_iocb(phba, elsiocb); |
2127 | return 1; | 2118 | return 1; |
@@ -2130,9 +2121,10 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, | |||
2130 | } | 2121 | } |
2131 | 2122 | ||
2132 | int | 2123 | int |
2133 | lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb, | 2124 | lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, |
2134 | struct lpfc_nodelist *ndlp) | 2125 | struct lpfc_nodelist *ndlp) |
2135 | { | 2126 | { |
2127 | struct lpfc_hba *phba = vport->phba; | ||
2136 | PRLI *npr; | 2128 | PRLI *npr; |
2137 | lpfc_vpd_t *vpd; | 2129 | lpfc_vpd_t *vpd; |
2138 | IOCB_t *icmd; | 2130 | IOCB_t *icmd; |
@@ -2148,8 +2140,10 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb, | |||
2148 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 2140 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
2149 | 2141 | ||
2150 | cmdsize = sizeof (uint32_t) + sizeof (PRLI); | 2142 | cmdsize = sizeof (uint32_t) + sizeof (PRLI); |
2151 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, ndlp, | 2143 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, |
2152 | ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK))); | 2144 | ndlp->nlp_DID, |
2145 | (ELS_CMD_ACC | | ||
2146 | (ELS_CMD_PRLI & ~ELS_RSP_MASK))); | ||
2153 | if (!elsiocb) | 2147 | if (!elsiocb) |
2154 | return 1; | 2148 | return 1; |
2155 | 2149 | ||
@@ -2196,9 +2190,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb, | |||
2196 | phba->fc_stat.elsXmitACC++; | 2190 | phba->fc_stat.elsXmitACC++; |
2197 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2191 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; |
2198 | 2192 | ||
2199 | spin_lock_irq(phba->host->host_lock); | ||
2200 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 2193 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
2201 | spin_unlock_irq(phba->host->host_lock); | ||
2202 | if (rc == IOCB_ERROR) { | 2194 | if (rc == IOCB_ERROR) { |
2203 | lpfc_els_free_iocb(phba, elsiocb); | 2195 | lpfc_els_free_iocb(phba, elsiocb); |
2204 | return 1; | 2196 | return 1; |
@@ -2207,12 +2199,12 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb, | |||
2207 | } | 2199 | } |
2208 | 2200 | ||
2209 | static int | 2201 | static int |
2210 | lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, | 2202 | lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, |
2211 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) | 2203 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) |
2212 | { | 2204 | { |
2205 | struct lpfc_hba *phba = vport->phba; | ||
2213 | RNID *rn; | 2206 | RNID *rn; |
2214 | IOCB_t *icmd; | 2207 | IOCB_t *icmd, *oldcmd; |
2215 | IOCB_t *oldcmd; | ||
2216 | struct lpfc_iocbq *elsiocb; | 2208 | struct lpfc_iocbq *elsiocb; |
2217 | struct lpfc_sli_ring *pring; | 2209 | struct lpfc_sli_ring *pring; |
2218 | struct lpfc_sli *psli; | 2210 | struct lpfc_sli *psli; |
@@ -2228,8 +2220,8 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, | |||
2228 | if (format) | 2220 | if (format) |
2229 | cmdsize += sizeof (RNID_TOP_DISC); | 2221 | cmdsize += sizeof (RNID_TOP_DISC); |
2230 | 2222 | ||
2231 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 2223 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, |
2232 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); | 2224 | ndlp->nlp_DID, ELS_CMD_ACC); |
2233 | if (!elsiocb) | 2225 | if (!elsiocb) |
2234 | return 1; | 2226 | return 1; |
2235 | 2227 | ||
@@ -2253,8 +2245,8 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, | |||
2253 | rn = (RNID *) (pcmd); | 2245 | rn = (RNID *) (pcmd); |
2254 | rn->Format = format; | 2246 | rn->Format = format; |
2255 | rn->CommonLen = (2 * sizeof (struct lpfc_name)); | 2247 | rn->CommonLen = (2 * sizeof (struct lpfc_name)); |
2256 | memcpy(&rn->portName, &phba->fc_portname, sizeof (struct lpfc_name)); | 2248 | memcpy(&rn->portName, &vport->fc_portname, sizeof (struct lpfc_name)); |
2257 | memcpy(&rn->nodeName, &phba->fc_nodename, sizeof (struct lpfc_name)); | 2249 | memcpy(&rn->nodeName, &vport->fc_nodename, sizeof (struct lpfc_name)); |
2258 | switch (format) { | 2250 | switch (format) { |
2259 | case 0: | 2251 | case 0: |
2260 | rn->SpecificLen = 0; | 2252 | rn->SpecificLen = 0; |
@@ -2262,7 +2254,7 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, | |||
2262 | case RNID_TOPOLOGY_DISC: | 2254 | case RNID_TOPOLOGY_DISC: |
2263 | rn->SpecificLen = sizeof (RNID_TOP_DISC); | 2255 | rn->SpecificLen = sizeof (RNID_TOP_DISC); |
2264 | memcpy(&rn->un.topologyDisc.portName, | 2256 | memcpy(&rn->un.topologyDisc.portName, |
2265 | &phba->fc_portname, sizeof (struct lpfc_name)); | 2257 | &vport->fc_portname, sizeof (struct lpfc_name)); |
2266 | rn->un.topologyDisc.unitType = RNID_HBA; | 2258 | rn->un.topologyDisc.unitType = RNID_HBA; |
2267 | rn->un.topologyDisc.physPort = 0; | 2259 | rn->un.topologyDisc.physPort = 0; |
2268 | rn->un.topologyDisc.attachedNodes = 0; | 2260 | rn->un.topologyDisc.attachedNodes = 0; |
@@ -2279,9 +2271,7 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, | |||
2279 | elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, | 2271 | elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, |
2280 | * it could be freed */ | 2272 | * it could be freed */ |
2281 | 2273 | ||
2282 | spin_lock_irq(phba->host->host_lock); | ||
2283 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 2274 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
2284 | spin_unlock_irq(phba->host->host_lock); | ||
2285 | if (rc == IOCB_ERROR) { | 2275 | if (rc == IOCB_ERROR) { |
2286 | lpfc_els_free_iocb(phba, elsiocb); | 2276 | lpfc_els_free_iocb(phba, elsiocb); |
2287 | return 1; | 2277 | return 1; |
@@ -2290,120 +2280,122 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, | |||
2290 | } | 2280 | } |
2291 | 2281 | ||
2292 | int | 2282 | int |
2293 | lpfc_els_disc_adisc(struct lpfc_hba *phba) | 2283 | lpfc_els_disc_adisc(struct lpfc_vport *vport) |
2294 | { | 2284 | { |
2295 | int sentadisc; | 2285 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
2296 | struct lpfc_nodelist *ndlp, *next_ndlp; | 2286 | struct lpfc_nodelist *ndlp, *next_ndlp; |
2287 | int sentadisc = 0; | ||
2297 | 2288 | ||
2298 | sentadisc = 0; | ||
2299 | /* go thru NPR nodes and issue any remaining ELS ADISCs */ | 2289 | /* go thru NPR nodes and issue any remaining ELS ADISCs */ |
2300 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { | 2290 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
2301 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && | 2291 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && |
2302 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && | 2292 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && |
2303 | (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) { | 2293 | (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) { |
2304 | spin_lock_irq(phba->host->host_lock); | 2294 | spin_lock_irq(shost->host_lock); |
2305 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 2295 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
2306 | spin_unlock_irq(phba->host->host_lock); | 2296 | spin_unlock_irq(shost->host_lock); |
2307 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2297 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2308 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); | 2298 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); |
2309 | lpfc_issue_els_adisc(phba, ndlp, 0); | 2299 | lpfc_issue_els_adisc(vport, ndlp, 0); |
2310 | sentadisc++; | 2300 | sentadisc++; |
2311 | phba->num_disc_nodes++; | 2301 | vport->num_disc_nodes++; |
2312 | if (phba->num_disc_nodes >= | 2302 | if (vport->num_disc_nodes >= |
2313 | phba->cfg_discovery_threads) { | 2303 | vport->phba->cfg_discovery_threads) { |
2314 | spin_lock_irq(phba->host->host_lock); | 2304 | spin_lock_irq(shost->host_lock); |
2315 | phba->fc_flag |= FC_NLP_MORE; | 2305 | vport->fc_flag |= FC_NLP_MORE; |
2316 | spin_unlock_irq(phba->host->host_lock); | 2306 | spin_unlock_irq(shost->host_lock); |
2317 | break; | 2307 | break; |
2318 | } | 2308 | } |
2319 | } | 2309 | } |
2320 | } | 2310 | } |
2321 | if (sentadisc == 0) { | 2311 | if (sentadisc == 0) { |
2322 | spin_lock_irq(phba->host->host_lock); | 2312 | spin_lock_irq(shost->host_lock); |
2323 | phba->fc_flag &= ~FC_NLP_MORE; | 2313 | vport->fc_flag &= ~FC_NLP_MORE; |
2324 | spin_unlock_irq(phba->host->host_lock); | 2314 | spin_unlock_irq(shost->host_lock); |
2325 | } | 2315 | } |
2326 | return sentadisc; | 2316 | return sentadisc; |
2327 | } | 2317 | } |
2328 | 2318 | ||
2329 | int | 2319 | int |
2330 | lpfc_els_disc_plogi(struct lpfc_hba * phba) | 2320 | lpfc_els_disc_plogi(struct lpfc_vport *vport) |
2331 | { | 2321 | { |
2332 | int sentplogi; | 2322 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
2333 | struct lpfc_nodelist *ndlp, *next_ndlp; | 2323 | struct lpfc_nodelist *ndlp, *next_ndlp; |
2324 | int sentplogi = 0; | ||
2334 | 2325 | ||
2335 | sentplogi = 0; | 2326 | /* go thru NPR nodes and issue any remaining ELS PLOGIs */ |
2336 | /* go thru NPR list and issue any remaining ELS PLOGIs */ | 2327 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
2337 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { | ||
2338 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && | 2328 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && |
2339 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && | 2329 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && |
2340 | (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 && | 2330 | (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 && |
2341 | (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) { | 2331 | (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) { |
2342 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2332 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2343 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 2333 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
2344 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 2334 | lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); |
2345 | sentplogi++; | 2335 | sentplogi++; |
2346 | phba->num_disc_nodes++; | 2336 | vport->num_disc_nodes++; |
2347 | if (phba->num_disc_nodes >= | 2337 | if (vport->num_disc_nodes >= |
2348 | phba->cfg_discovery_threads) { | 2338 | vport->phba->cfg_discovery_threads) { |
2349 | spin_lock_irq(phba->host->host_lock); | 2339 | spin_lock_irq(shost->host_lock); |
2350 | phba->fc_flag |= FC_NLP_MORE; | 2340 | vport->fc_flag |= FC_NLP_MORE; |
2351 | spin_unlock_irq(phba->host->host_lock); | 2341 | spin_unlock_irq(shost->host_lock); |
2352 | break; | 2342 | break; |
2353 | } | 2343 | } |
2354 | } | 2344 | } |
2355 | } | 2345 | } |
2356 | if (sentplogi == 0) { | 2346 | if (sentplogi == 0) { |
2357 | spin_lock_irq(phba->host->host_lock); | 2347 | spin_lock_irq(shost->host_lock); |
2358 | phba->fc_flag &= ~FC_NLP_MORE; | 2348 | vport->fc_flag &= ~FC_NLP_MORE; |
2359 | spin_unlock_irq(phba->host->host_lock); | 2349 | spin_unlock_irq(shost->host_lock); |
2360 | } | 2350 | } |
2361 | return sentplogi; | 2351 | return sentplogi; |
2362 | } | 2352 | } |
2363 | 2353 | ||
2364 | int | 2354 | int |
2365 | lpfc_els_flush_rscn(struct lpfc_hba * phba) | 2355 | lpfc_els_flush_rscn(struct lpfc_vport *vport) |
2366 | { | 2356 | { |
2357 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2358 | struct lpfc_hba *phba = vport->phba; | ||
2367 | struct lpfc_dmabuf *mp; | 2359 | struct lpfc_dmabuf *mp; |
2368 | int i; | 2360 | int i; |
2369 | 2361 | ||
2370 | for (i = 0; i < phba->fc_rscn_id_cnt; i++) { | 2362 | for (i = 0; i < vport->fc_rscn_id_cnt; i++) { |
2371 | mp = phba->fc_rscn_id_list[i]; | 2363 | mp = vport->fc_rscn_id_list[i]; |
2372 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 2364 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
2373 | kfree(mp); | 2365 | kfree(mp); |
2374 | phba->fc_rscn_id_list[i] = NULL; | 2366 | vport->fc_rscn_id_list[i] = NULL; |
2375 | } | 2367 | } |
2376 | phba->fc_rscn_id_cnt = 0; | 2368 | spin_lock_irq(shost->host_lock); |
2377 | spin_lock_irq(phba->host->host_lock); | 2369 | vport->fc_rscn_id_cnt = 0; |
2378 | phba->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY); | 2370 | vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY); |
2379 | spin_unlock_irq(phba->host->host_lock); | 2371 | spin_unlock_irq(shost->host_lock); |
2380 | lpfc_can_disctmo(phba); | 2372 | lpfc_can_disctmo(vport); |
2381 | return 0; | 2373 | return 0; |
2382 | } | 2374 | } |
2383 | 2375 | ||
2384 | int | 2376 | int |
2385 | lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) | 2377 | lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) |
2386 | { | 2378 | { |
2387 | D_ID ns_did; | 2379 | D_ID ns_did; |
2388 | D_ID rscn_did; | 2380 | D_ID rscn_did; |
2389 | struct lpfc_dmabuf *mp; | 2381 | struct lpfc_dmabuf *mp; |
2390 | uint32_t *lp; | 2382 | uint32_t *lp; |
2391 | uint32_t payload_len, cmd, i, match; | 2383 | uint32_t payload_len, cmd, i, match; |
2384 | struct lpfc_hba *phba = vport->phba; | ||
2392 | 2385 | ||
2393 | ns_did.un.word = did; | 2386 | ns_did.un.word = did; |
2394 | match = 0; | 2387 | match = 0; |
2395 | 2388 | ||
2396 | /* Never match fabric nodes for RSCNs */ | 2389 | /* Never match fabric nodes for RSCNs */ |
2397 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) | 2390 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) |
2398 | return(0); | 2391 | return 0; |
2399 | 2392 | ||
2400 | /* If we are doing a FULL RSCN rediscovery, match everything */ | 2393 | /* If we are doing a FULL RSCN rediscovery, match everything */ |
2401 | if (phba->fc_flag & FC_RSCN_DISCOVERY) { | 2394 | if (vport->fc_flag & FC_RSCN_DISCOVERY) |
2402 | return did; | 2395 | return did; |
2403 | } | ||
2404 | 2396 | ||
2405 | for (i = 0; i < phba->fc_rscn_id_cnt; i++) { | 2397 | for (i = 0; i < vport->fc_rscn_id_cnt; i++) { |
2406 | mp = phba->fc_rscn_id_list[i]; | 2398 | mp = vport->fc_rscn_id_list[i]; |
2407 | lp = (uint32_t *) mp->virt; | 2399 | lp = (uint32_t *) mp->virt; |
2408 | cmd = *lp++; | 2400 | cmd = *lp++; |
2409 | payload_len = be32_to_cpu(cmd) & 0xffff; /* payload length */ | 2401 | payload_len = be32_to_cpu(cmd) & 0xffff; /* payload length */ |
@@ -2414,44 +2406,38 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) | |||
2414 | payload_len -= sizeof (uint32_t); | 2406 | payload_len -= sizeof (uint32_t); |
2415 | switch (rscn_did.un.b.resv) { | 2407 | switch (rscn_did.un.b.resv) { |
2416 | case 0: /* Single N_Port ID effected */ | 2408 | case 0: /* Single N_Port ID effected */ |
2417 | if (ns_did.un.word == rscn_did.un.word) { | 2409 | if (ns_did.un.word == rscn_did.un.word) |
2418 | match = did; | 2410 | match = did; |
2419 | } | ||
2420 | break; | 2411 | break; |
2421 | case 1: /* Whole N_Port Area effected */ | 2412 | case 1: /* Whole N_Port Area effected */ |
2422 | if ((ns_did.un.b.domain == rscn_did.un.b.domain) | 2413 | if ((ns_did.un.b.domain == rscn_did.un.b.domain) |
2423 | && (ns_did.un.b.area == rscn_did.un.b.area)) | 2414 | && (ns_did.un.b.area == rscn_did.un.b.area)) |
2424 | { | ||
2425 | match = did; | 2415 | match = did; |
2426 | } | ||
2427 | break; | 2416 | break; |
2428 | case 2: /* Whole N_Port Domain effected */ | 2417 | case 2: /* Whole N_Port Domain effected */ |
2429 | if (ns_did.un.b.domain == rscn_did.un.b.domain) | 2418 | if (ns_did.un.b.domain == rscn_did.un.b.domain) |
2430 | { | ||
2431 | match = did; | 2419 | match = did; |
2432 | } | ||
2433 | break; | 2420 | break; |
2434 | case 3: /* Whole Fabric effected */ | 2421 | case 3: /* Whole Fabric effected */ |
2435 | match = did; | 2422 | match = did; |
2436 | break; | 2423 | break; |
2437 | default: | 2424 | default: |
2438 | /* Unknown Identifier in RSCN list */ | 2425 | /* Unknown Identifier in RSCN node */ |
2439 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 2426 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
2440 | "%d:0217 Unknown Identifier in " | 2427 | "%d:0217 Unknown Identifier in " |
2441 | "RSCN payload Data: x%x\n", | 2428 | "RSCN payload Data: x%x\n", |
2442 | phba->brd_no, rscn_did.un.word); | 2429 | phba->brd_no, rscn_did.un.word); |
2443 | break; | 2430 | break; |
2444 | } | 2431 | } |
2445 | if (match) { | 2432 | if (match) |
2446 | break; | 2433 | break; |
2447 | } | 2434 | } |
2448 | } | 2435 | } |
2449 | } | ||
2450 | return match; | 2436 | return match; |
2451 | } | 2437 | } |
2452 | 2438 | ||
2453 | static int | 2439 | static int |
2454 | lpfc_rscn_recovery_check(struct lpfc_hba *phba) | 2440 | lpfc_rscn_recovery_check(struct lpfc_vport *vport) |
2455 | { | 2441 | { |
2456 | struct lpfc_nodelist *ndlp = NULL; | 2442 | struct lpfc_nodelist *ndlp = NULL; |
2457 | 2443 | ||
@@ -2459,12 +2445,12 @@ lpfc_rscn_recovery_check(struct lpfc_hba *phba) | |||
2459 | * them to NPR state. | 2445 | * them to NPR state. |
2460 | */ | 2446 | */ |
2461 | 2447 | ||
2462 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { | 2448 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
2463 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE || | 2449 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE || |
2464 | lpfc_rscn_payload_check(phba, ndlp->nlp_DID) == 0) | 2450 | lpfc_rscn_payload_check(vport, ndlp->nlp_DID) == 0) |
2465 | continue; | 2451 | continue; |
2466 | 2452 | ||
2467 | lpfc_disc_state_machine(phba, ndlp, NULL, | 2453 | lpfc_disc_state_machine(vport, ndlp, NULL, |
2468 | NLP_EVT_DEVICE_RECOVERY); | 2454 | NLP_EVT_DEVICE_RECOVERY); |
2469 | 2455 | ||
2470 | /* | 2456 | /* |
@@ -2472,17 +2458,18 @@ lpfc_rscn_recovery_check(struct lpfc_hba *phba) | |||
2472 | * recovery event. | 2458 | * recovery event. |
2473 | */ | 2459 | */ |
2474 | if (ndlp->nlp_flag & NLP_DELAY_TMO) | 2460 | if (ndlp->nlp_flag & NLP_DELAY_TMO) |
2475 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 2461 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
2476 | } | 2462 | } |
2477 | 2463 | ||
2478 | return 0; | 2464 | return 0; |
2479 | } | 2465 | } |
2480 | 2466 | ||
2481 | static int | 2467 | static int |
2482 | lpfc_els_rcv_rscn(struct lpfc_hba * phba, | 2468 | lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
2483 | struct lpfc_iocbq * cmdiocb, | 2469 | struct lpfc_nodelist *ndlp, uint8_t newnode) |
2484 | struct lpfc_nodelist * ndlp, uint8_t newnode) | ||
2485 | { | 2470 | { |
2471 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2472 | struct lpfc_hba *phba = vport->phba; | ||
2486 | struct lpfc_dmabuf *pcmd; | 2473 | struct lpfc_dmabuf *pcmd; |
2487 | uint32_t *lp; | 2474 | uint32_t *lp; |
2488 | IOCB_t *icmd; | 2475 | IOCB_t *icmd; |
@@ -2503,18 +2490,18 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, | |||
2503 | KERN_INFO, | 2490 | KERN_INFO, |
2504 | LOG_DISCOVERY, | 2491 | LOG_DISCOVERY, |
2505 | "%d:0214 RSCN received Data: x%x x%x x%x x%x\n", | 2492 | "%d:0214 RSCN received Data: x%x x%x x%x x%x\n", |
2506 | phba->brd_no, | 2493 | phba->brd_no, vport->fc_flag, payload_len, *lp, |
2507 | phba->fc_flag, payload_len, *lp, phba->fc_rscn_id_cnt); | 2494 | vport->fc_rscn_id_cnt); |
2508 | 2495 | ||
2509 | for (i = 0; i < payload_len/sizeof(uint32_t); i++) | 2496 | for (i = 0; i < payload_len/sizeof(uint32_t); i++) |
2510 | fc_host_post_event(phba->host, fc_get_event_number(), | 2497 | fc_host_post_event(shost, fc_get_event_number(), |
2511 | FCH_EVT_RSCN, lp[i]); | 2498 | FCH_EVT_RSCN, lp[i]); |
2512 | 2499 | ||
2513 | /* If we are about to begin discovery, just ACC the RSCN. | 2500 | /* If we are about to begin discovery, just ACC the RSCN. |
2514 | * Discovery processing will satisfy it. | 2501 | * Discovery processing will satisfy it. |
2515 | */ | 2502 | */ |
2516 | if (phba->hba_state <= LPFC_NS_QRY) { | 2503 | if (vport->port_state <= LPFC_NS_QRY) { |
2517 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, | 2504 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, |
2518 | newnode); | 2505 | newnode); |
2519 | return 0; | 2506 | return 0; |
2520 | } | 2507 | } |
@@ -2522,13 +2509,13 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, | |||
2522 | /* If we are already processing an RSCN, save the received | 2509 | /* If we are already processing an RSCN, save the received |
2523 | * RSCN payload buffer, cmdiocb->context2 to process later. | 2510 | * RSCN payload buffer, cmdiocb->context2 to process later. |
2524 | */ | 2511 | */ |
2525 | if (phba->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) { | 2512 | if (vport->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) { |
2526 | if ((phba->fc_rscn_id_cnt < FC_MAX_HOLD_RSCN) && | 2513 | if ((vport->fc_rscn_id_cnt < FC_MAX_HOLD_RSCN) && |
2527 | !(phba->fc_flag & FC_RSCN_DISCOVERY)) { | 2514 | !(vport->fc_flag & FC_RSCN_DISCOVERY)) { |
2528 | spin_lock_irq(phba->host->host_lock); | 2515 | spin_lock_irq(shost->host_lock); |
2529 | phba->fc_flag |= FC_RSCN_MODE; | 2516 | vport->fc_flag |= FC_RSCN_MODE; |
2530 | spin_unlock_irq(phba->host->host_lock); | 2517 | spin_unlock_irq(shost->host_lock); |
2531 | phba->fc_rscn_id_list[phba->fc_rscn_id_cnt++] = pcmd; | 2518 | vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd; |
2532 | 2519 | ||
2533 | /* If we zero, cmdiocb->context2, the calling | 2520 | /* If we zero, cmdiocb->context2, the calling |
2534 | * routine will not try to free it. | 2521 | * routine will not try to free it. |
@@ -2539,54 +2526,59 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, | |||
2539 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 2526 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
2540 | "%d:0235 Deferred RSCN " | 2527 | "%d:0235 Deferred RSCN " |
2541 | "Data: x%x x%x x%x\n", | 2528 | "Data: x%x x%x x%x\n", |
2542 | phba->brd_no, phba->fc_rscn_id_cnt, | 2529 | phba->brd_no, vport->fc_rscn_id_cnt, |
2543 | phba->fc_flag, phba->hba_state); | 2530 | vport->fc_flag, |
2531 | vport->port_state); | ||
2544 | } else { | 2532 | } else { |
2545 | spin_lock_irq(phba->host->host_lock); | 2533 | spin_lock_irq(shost->host_lock); |
2546 | phba->fc_flag |= FC_RSCN_DISCOVERY; | 2534 | vport->fc_flag |= FC_RSCN_DISCOVERY; |
2547 | spin_unlock_irq(phba->host->host_lock); | 2535 | spin_unlock_irq(shost->host_lock); |
2548 | /* ReDiscovery RSCN */ | 2536 | /* ReDiscovery RSCN */ |
2549 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 2537 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
2550 | "%d:0234 ReDiscovery RSCN " | 2538 | "%d:0234 ReDiscovery RSCN " |
2551 | "Data: x%x x%x x%x\n", | 2539 | "Data: x%x x%x x%x\n", |
2552 | phba->brd_no, phba->fc_rscn_id_cnt, | 2540 | phba->brd_no, vport->fc_rscn_id_cnt, |
2553 | phba->fc_flag, phba->hba_state); | 2541 | vport->fc_flag, |
2542 | vport->port_state); | ||
2554 | } | 2543 | } |
2555 | /* Send back ACC */ | 2544 | /* Send back ACC */ |
2556 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, | 2545 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, |
2557 | newnode); | 2546 | newnode); |
2558 | 2547 | ||
2559 | /* send RECOVERY event for ALL nodes that match RSCN payload */ | 2548 | /* send RECOVERY event for ALL nodes that match RSCN payload */ |
2560 | lpfc_rscn_recovery_check(phba); | 2549 | lpfc_rscn_recovery_check(vport); |
2561 | return 0; | 2550 | return 0; |
2562 | } | 2551 | } |
2563 | 2552 | ||
2564 | phba->fc_flag |= FC_RSCN_MODE; | 2553 | spin_lock_irq(shost->host_lock); |
2565 | phba->fc_rscn_id_list[phba->fc_rscn_id_cnt++] = pcmd; | 2554 | vport->fc_flag |= FC_RSCN_MODE; |
2555 | spin_unlock_irq(shost->host_lock); | ||
2556 | vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd; | ||
2566 | /* | 2557 | /* |
2567 | * If we zero, cmdiocb->context2, the calling routine will | 2558 | * If we zero, cmdiocb->context2, the calling routine will |
2568 | * not try to free it. | 2559 | * not try to free it. |
2569 | */ | 2560 | */ |
2570 | cmdiocb->context2 = NULL; | 2561 | cmdiocb->context2 = NULL; |
2571 | 2562 | ||
2572 | lpfc_set_disctmo(phba); | 2563 | lpfc_set_disctmo(vport); |
2573 | 2564 | ||
2574 | /* Send back ACC */ | 2565 | /* Send back ACC */ |
2575 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode); | 2566 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode); |
2576 | 2567 | ||
2577 | /* send RECOVERY event for ALL nodes that match RSCN payload */ | 2568 | /* send RECOVERY event for ALL nodes that match RSCN payload */ |
2578 | lpfc_rscn_recovery_check(phba); | 2569 | lpfc_rscn_recovery_check(vport); |
2579 | 2570 | ||
2580 | return lpfc_els_handle_rscn(phba); | 2571 | return lpfc_els_handle_rscn(vport); |
2581 | } | 2572 | } |
2582 | 2573 | ||
2583 | int | 2574 | int |
2584 | lpfc_els_handle_rscn(struct lpfc_hba * phba) | 2575 | lpfc_els_handle_rscn(struct lpfc_vport *vport) |
2585 | { | 2576 | { |
2586 | struct lpfc_nodelist *ndlp; | 2577 | struct lpfc_nodelist *ndlp; |
2578 | struct lpfc_hba *phba = vport->phba; | ||
2587 | 2579 | ||
2588 | /* Start timer for RSCN processing */ | 2580 | /* Start timer for RSCN processing */ |
2589 | lpfc_set_disctmo(phba); | 2581 | lpfc_set_disctmo(vport); |
2590 | 2582 | ||
2591 | /* RSCN processed */ | 2583 | /* RSCN processed */ |
2592 | lpfc_printf_log(phba, | 2584 | lpfc_printf_log(phba, |
@@ -2594,53 +2586,53 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) | |||
2594 | LOG_DISCOVERY, | 2586 | LOG_DISCOVERY, |
2595 | "%d:0215 RSCN processed Data: x%x x%x x%x x%x\n", | 2587 | "%d:0215 RSCN processed Data: x%x x%x x%x x%x\n", |
2596 | phba->brd_no, | 2588 | phba->brd_no, |
2597 | phba->fc_flag, 0, phba->fc_rscn_id_cnt, | 2589 | vport->fc_flag, 0, vport->fc_rscn_id_cnt, |
2598 | phba->hba_state); | 2590 | vport->port_state); |
2599 | 2591 | ||
2600 | /* To process RSCN, first compare RSCN data with NameServer */ | 2592 | /* To process RSCN, first compare RSCN data with NameServer */ |
2601 | phba->fc_ns_retry = 0; | 2593 | vport->fc_ns_retry = 0; |
2602 | ndlp = lpfc_findnode_did(phba, NameServer_DID); | 2594 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
2603 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 2595 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { |
2604 | /* Good ndlp, issue CT Request to NameServer */ | 2596 | /* Good ndlp, issue CT Request to NameServer */ |
2605 | if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { | 2597 | if (lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT) == 0) |
2606 | /* Wait for NameServer query cmpl before we can | 2598 | /* Wait for NameServer query cmpl before we can |
2607 | continue */ | 2599 | continue */ |
2608 | return 1; | 2600 | return 1; |
2609 | } | ||
2610 | } else { | 2601 | } else { |
2611 | /* If login to NameServer does not exist, issue one */ | 2602 | /* If login to NameServer does not exist, issue one */ |
2612 | /* Good status, issue PLOGI to NameServer */ | 2603 | /* Good status, issue PLOGI to NameServer */ |
2613 | ndlp = lpfc_findnode_did(phba, NameServer_DID); | 2604 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
2614 | if (ndlp) { | 2605 | if (ndlp) |
2615 | /* Wait for NameServer login cmpl before we can | 2606 | /* Wait for NameServer login cmpl before we can |
2616 | continue */ | 2607 | continue */ |
2617 | return 1; | 2608 | return 1; |
2618 | } | 2609 | |
2619 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | 2610 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
2620 | if (!ndlp) { | 2611 | if (!ndlp) { |
2621 | lpfc_els_flush_rscn(phba); | 2612 | lpfc_els_flush_rscn(vport); |
2622 | return 0; | 2613 | return 0; |
2623 | } else { | 2614 | } else { |
2624 | lpfc_nlp_init(phba, ndlp, NameServer_DID); | 2615 | lpfc_nlp_init(vport, ndlp, NameServer_DID); |
2625 | ndlp->nlp_type |= NLP_FABRIC; | 2616 | ndlp->nlp_type |= NLP_FABRIC; |
2626 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2617 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2627 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 2618 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
2628 | lpfc_issue_els_plogi(phba, NameServer_DID, 0); | 2619 | lpfc_issue_els_plogi(vport, NameServer_DID, 0); |
2629 | /* Wait for NameServer login cmpl before we can | 2620 | /* Wait for NameServer login cmpl before we can |
2630 | continue */ | 2621 | continue */ |
2631 | return 1; | 2622 | return 1; |
2632 | } | 2623 | } |
2633 | } | 2624 | } |
2634 | 2625 | ||
2635 | lpfc_els_flush_rscn(phba); | 2626 | lpfc_els_flush_rscn(vport); |
2636 | return 0; | 2627 | return 0; |
2637 | } | 2628 | } |
2638 | 2629 | ||
2639 | static int | 2630 | static int |
2640 | lpfc_els_rcv_flogi(struct lpfc_hba * phba, | 2631 | lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
2641 | struct lpfc_iocbq * cmdiocb, | 2632 | struct lpfc_nodelist *ndlp, uint8_t newnode) |
2642 | struct lpfc_nodelist * ndlp, uint8_t newnode) | ||
2643 | { | 2633 | { |
2634 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2635 | struct lpfc_hba *phba = vport->phba; | ||
2644 | struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 2636 | struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
2645 | uint32_t *lp = (uint32_t *) pcmd->virt; | 2637 | uint32_t *lp = (uint32_t *) pcmd->virt; |
2646 | IOCB_t *icmd = &cmdiocb->iocb; | 2638 | IOCB_t *icmd = &cmdiocb->iocb; |
@@ -2655,7 +2647,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, | |||
2655 | 2647 | ||
2656 | /* FLOGI received */ | 2648 | /* FLOGI received */ |
2657 | 2649 | ||
2658 | lpfc_set_disctmo(phba); | 2650 | lpfc_set_disctmo(vport); |
2659 | 2651 | ||
2660 | if (phba->fc_topology == TOPOLOGY_LOOP) { | 2652 | if (phba->fc_topology == TOPOLOGY_LOOP) { |
2661 | /* We should never receive a FLOGI in loop mode, ignore it */ | 2653 | /* We should never receive a FLOGI in loop mode, ignore it */ |
@@ -2672,19 +2664,19 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, | |||
2672 | 2664 | ||
2673 | did = Fabric_DID; | 2665 | did = Fabric_DID; |
2674 | 2666 | ||
2675 | if ((lpfc_check_sparm(phba, ndlp, sp, CLASS3))) { | 2667 | if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3))) { |
2676 | /* For a FLOGI we accept, then if our portname is greater | 2668 | /* For a FLOGI we accept, then if our portname is greater |
2677 | * then the remote portname we initiate Nport login. | 2669 | * then the remote portname we initiate Nport login. |
2678 | */ | 2670 | */ |
2679 | 2671 | ||
2680 | rc = memcmp(&phba->fc_portname, &sp->portName, | 2672 | rc = memcmp(&vport->fc_portname, &sp->portName, |
2681 | sizeof (struct lpfc_name)); | 2673 | sizeof (struct lpfc_name)); |
2682 | 2674 | ||
2683 | if (!rc) { | 2675 | if (!rc) { |
2684 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, | 2676 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
2685 | GFP_KERNEL)) == 0) { | 2677 | if (!mbox) |
2686 | return 1; | 2678 | return 1; |
2687 | } | 2679 | |
2688 | lpfc_linkdown(phba); | 2680 | lpfc_linkdown(phba); |
2689 | lpfc_init_link(phba, mbox, | 2681 | lpfc_init_link(phba, mbox, |
2690 | phba->cfg_topology, | 2682 | phba->cfg_topology, |
@@ -2699,31 +2691,33 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, | |||
2699 | } | 2691 | } |
2700 | return 1; | 2692 | return 1; |
2701 | } else if (rc > 0) { /* greater than */ | 2693 | } else if (rc > 0) { /* greater than */ |
2702 | spin_lock_irq(phba->host->host_lock); | 2694 | spin_lock_irq(shost->host_lock); |
2703 | phba->fc_flag |= FC_PT2PT_PLOGI; | 2695 | vport->fc_flag |= FC_PT2PT_PLOGI; |
2704 | spin_unlock_irq(phba->host->host_lock); | 2696 | spin_unlock_irq(shost->host_lock); |
2705 | } | 2697 | } |
2706 | phba->fc_flag |= FC_PT2PT; | 2698 | spin_lock_irq(shost->host_lock); |
2707 | phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); | 2699 | vport->fc_flag |= FC_PT2PT; |
2700 | vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); | ||
2701 | spin_unlock_irq(shost->host_lock); | ||
2708 | } else { | 2702 | } else { |
2709 | /* Reject this request because invalid parameters */ | 2703 | /* Reject this request because invalid parameters */ |
2710 | stat.un.b.lsRjtRsvd0 = 0; | 2704 | stat.un.b.lsRjtRsvd0 = 0; |
2711 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 2705 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
2712 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; | 2706 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; |
2713 | stat.un.b.vendorUnique = 0; | 2707 | stat.un.b.vendorUnique = 0; |
2714 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 2708 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
2715 | return 1; | 2709 | return 1; |
2716 | } | 2710 | } |
2717 | 2711 | ||
2718 | /* Send back ACC */ | 2712 | /* Send back ACC */ |
2719 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode); | 2713 | lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode); |
2720 | 2714 | ||
2721 | return 0; | 2715 | return 0; |
2722 | } | 2716 | } |
2723 | 2717 | ||
2724 | static int | 2718 | static int |
2725 | lpfc_els_rcv_rnid(struct lpfc_hba * phba, | 2719 | lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
2726 | struct lpfc_iocbq * cmdiocb, struct lpfc_nodelist * ndlp) | 2720 | struct lpfc_nodelist *ndlp) |
2727 | { | 2721 | { |
2728 | struct lpfc_dmabuf *pcmd; | 2722 | struct lpfc_dmabuf *pcmd; |
2729 | uint32_t *lp; | 2723 | uint32_t *lp; |
@@ -2746,7 +2740,7 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba, | |||
2746 | case 0: | 2740 | case 0: |
2747 | case RNID_TOPOLOGY_DISC: | 2741 | case RNID_TOPOLOGY_DISC: |
2748 | /* Send back ACC */ | 2742 | /* Send back ACC */ |
2749 | lpfc_els_rsp_rnid_acc(phba, rn->Format, cmdiocb, ndlp); | 2743 | lpfc_els_rsp_rnid_acc(vport, rn->Format, cmdiocb, ndlp); |
2750 | break; | 2744 | break; |
2751 | default: | 2745 | default: |
2752 | /* Reject this request because format not supported */ | 2746 | /* Reject this request because format not supported */ |
@@ -2754,14 +2748,14 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba, | |||
2754 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 2748 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
2755 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | 2749 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; |
2756 | stat.un.b.vendorUnique = 0; | 2750 | stat.un.b.vendorUnique = 0; |
2757 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 2751 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
2758 | } | 2752 | } |
2759 | return 0; | 2753 | return 0; |
2760 | } | 2754 | } |
2761 | 2755 | ||
2762 | static int | 2756 | static int |
2763 | lpfc_els_rcv_lirr(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 2757 | lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
2764 | struct lpfc_nodelist *ndlp) | 2758 | struct lpfc_nodelist *ndlp) |
2765 | { | 2759 | { |
2766 | struct ls_rjt stat; | 2760 | struct ls_rjt stat; |
2767 | 2761 | ||
@@ -2770,15 +2764,15 @@ lpfc_els_rcv_lirr(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2770 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 2764 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
2771 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | 2765 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; |
2772 | stat.un.b.vendorUnique = 0; | 2766 | stat.un.b.vendorUnique = 0; |
2773 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 2767 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
2774 | return 0; | 2768 | return 0; |
2775 | } | 2769 | } |
2776 | 2770 | ||
2777 | static void | 2771 | static void |
2778 | lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 2772 | lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
2779 | { | 2773 | { |
2780 | struct lpfc_sli *psli; | 2774 | struct lpfc_sli *psli = &phba->sli; |
2781 | struct lpfc_sli_ring *pring; | 2775 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; |
2782 | MAILBOX_t *mb; | 2776 | MAILBOX_t *mb; |
2783 | IOCB_t *icmd; | 2777 | IOCB_t *icmd; |
2784 | RPS_RSP *rps_rsp; | 2778 | RPS_RSP *rps_rsp; |
@@ -2788,8 +2782,6 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2788 | uint16_t xri, status; | 2782 | uint16_t xri, status; |
2789 | uint32_t cmdsize; | 2783 | uint32_t cmdsize; |
2790 | 2784 | ||
2791 | psli = &phba->sli; | ||
2792 | pring = &psli->ring[LPFC_ELS_RING]; | ||
2793 | mb = &pmb->mb; | 2785 | mb = &pmb->mb; |
2794 | 2786 | ||
2795 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 2787 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
@@ -2804,8 +2796,9 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2804 | 2796 | ||
2805 | cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); | 2797 | cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); |
2806 | mempool_free(pmb, phba->mbox_mem_pool); | 2798 | mempool_free(pmb, phba->mbox_mem_pool); |
2807 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, ndlp, | 2799 | elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize, |
2808 | ndlp->nlp_DID, ELS_CMD_ACC); | 2800 | lpfc_max_els_tries, ndlp, |
2801 | ndlp->nlp_DID, ELS_CMD_ACC); | ||
2809 | lpfc_nlp_put(ndlp); | 2802 | lpfc_nlp_put(ndlp); |
2810 | if (!elsiocb) | 2803 | if (!elsiocb) |
2811 | return; | 2804 | return; |
@@ -2822,7 +2815,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2822 | status = 0x10; | 2815 | status = 0x10; |
2823 | else | 2816 | else |
2824 | status = 0x8; | 2817 | status = 0x8; |
2825 | if (phba->fc_flag & FC_FABRIC) | 2818 | if (phba->pport->fc_flag & FC_FABRIC) |
2826 | status |= 0x4; | 2819 | status |= 0x4; |
2827 | 2820 | ||
2828 | rps_rsp->rsvd1 = 0; | 2821 | rps_rsp->rsvd1 = 0; |
@@ -2852,9 +2845,10 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2852 | } | 2845 | } |
2853 | 2846 | ||
2854 | static int | 2847 | static int |
2855 | lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2848 | lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
2856 | struct lpfc_nodelist * ndlp) | 2849 | struct lpfc_nodelist *ndlp) |
2857 | { | 2850 | { |
2851 | struct lpfc_hba *phba = vport->phba; | ||
2858 | uint32_t *lp; | 2852 | uint32_t *lp; |
2859 | uint8_t flag; | 2853 | uint8_t flag; |
2860 | LPFC_MBOXQ_t *mbox; | 2854 | LPFC_MBOXQ_t *mbox; |
@@ -2868,7 +2862,7 @@ lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
2868 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 2862 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
2869 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | 2863 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; |
2870 | stat.un.b.vendorUnique = 0; | 2864 | stat.un.b.vendorUnique = 0; |
2871 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 2865 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
2872 | } | 2866 | } |
2873 | 2867 | ||
2874 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 2868 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
@@ -2878,19 +2872,21 @@ lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
2878 | 2872 | ||
2879 | if ((flag == 0) || | 2873 | if ((flag == 0) || |
2880 | ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) || | 2874 | ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) || |
2881 | ((flag == 2) && (memcmp(&rps->un.portName, &phba->fc_portname, | 2875 | ((flag == 2) && (memcmp(&rps->un.portName, &vport->fc_portname, |
2882 | sizeof (struct lpfc_name)) == 0))) { | 2876 | sizeof (struct lpfc_name)) == 0))) { |
2883 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC))) { | 2877 | |
2878 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC); | ||
2879 | if (mbox) { | ||
2884 | lpfc_read_lnk_stat(phba, mbox); | 2880 | lpfc_read_lnk_stat(phba, mbox); |
2885 | mbox->context1 = | 2881 | mbox->context1 = |
2886 | (void *)((unsigned long)cmdiocb->iocb.ulpContext); | 2882 | (void *)((unsigned long)cmdiocb->iocb.ulpContext); |
2887 | mbox->context2 = lpfc_nlp_get(ndlp); | 2883 | mbox->context2 = lpfc_nlp_get(ndlp); |
2888 | mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; | 2884 | mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; |
2889 | if (lpfc_sli_issue_mbox (phba, mbox, | 2885 | if (lpfc_sli_issue_mbox (phba, mbox, |
2890 | (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) { | 2886 | (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) |
2891 | /* Mbox completion will send ELS Response */ | 2887 | /* Mbox completion will send ELS Response */ |
2892 | return 0; | 2888 | return 0; |
2893 | } | 2889 | |
2894 | lpfc_nlp_put(ndlp); | 2890 | lpfc_nlp_put(ndlp); |
2895 | mempool_free(mbox, phba->mbox_mem_pool); | 2891 | mempool_free(mbox, phba->mbox_mem_pool); |
2896 | } | 2892 | } |
@@ -2899,27 +2895,25 @@ lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
2899 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 2895 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
2900 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | 2896 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; |
2901 | stat.un.b.vendorUnique = 0; | 2897 | stat.un.b.vendorUnique = 0; |
2902 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 2898 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
2903 | return 0; | 2899 | return 0; |
2904 | } | 2900 | } |
2905 | 2901 | ||
2906 | static int | 2902 | static int |
2907 | lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize, | 2903 | lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, |
2908 | struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp) | 2904 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) |
2909 | { | 2905 | { |
2910 | IOCB_t *icmd; | 2906 | struct lpfc_hba *phba = vport->phba; |
2911 | IOCB_t *oldcmd; | 2907 | IOCB_t *icmd, *oldcmd; |
2912 | RPL_RSP rpl_rsp; | 2908 | RPL_RSP rpl_rsp; |
2913 | struct lpfc_iocbq *elsiocb; | 2909 | struct lpfc_iocbq *elsiocb; |
2914 | struct lpfc_sli_ring *pring; | 2910 | struct lpfc_sli *psli = &phba->sli; |
2915 | struct lpfc_sli *psli; | 2911 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; |
2916 | uint8_t *pcmd; | 2912 | uint8_t *pcmd; |
2917 | 2913 | ||
2918 | psli = &phba->sli; | 2914 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, |
2919 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 2915 | ndlp->nlp_DID, ELS_CMD_ACC); |
2920 | 2916 | ||
2921 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | ||
2922 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); | ||
2923 | if (!elsiocb) | 2917 | if (!elsiocb) |
2924 | return 1; | 2918 | return 1; |
2925 | 2919 | ||
@@ -2937,8 +2931,8 @@ lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize, | |||
2937 | rpl_rsp.listLen = be32_to_cpu(1); | 2931 | rpl_rsp.listLen = be32_to_cpu(1); |
2938 | rpl_rsp.index = 0; | 2932 | rpl_rsp.index = 0; |
2939 | rpl_rsp.port_num_blk.portNum = 0; | 2933 | rpl_rsp.port_num_blk.portNum = 0; |
2940 | rpl_rsp.port_num_blk.portID = be32_to_cpu(phba->fc_myDID); | 2934 | rpl_rsp.port_num_blk.portID = be32_to_cpu(vport->fc_myDID); |
2941 | memcpy(&rpl_rsp.port_num_blk.portName, &phba->fc_portname, | 2935 | memcpy(&rpl_rsp.port_num_blk.portName, &vport->fc_portname, |
2942 | sizeof(struct lpfc_name)); | 2936 | sizeof(struct lpfc_name)); |
2943 | 2937 | ||
2944 | memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t)); | 2938 | memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t)); |
@@ -2963,8 +2957,8 @@ lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize, | |||
2963 | } | 2957 | } |
2964 | 2958 | ||
2965 | static int | 2959 | static int |
2966 | lpfc_els_rcv_rpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2960 | lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
2967 | struct lpfc_nodelist * ndlp) | 2961 | struct lpfc_nodelist *ndlp) |
2968 | { | 2962 | { |
2969 | struct lpfc_dmabuf *pcmd; | 2963 | struct lpfc_dmabuf *pcmd; |
2970 | uint32_t *lp; | 2964 | uint32_t *lp; |
@@ -2979,7 +2973,7 @@ lpfc_els_rcv_rpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
2979 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 2973 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
2980 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | 2974 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; |
2981 | stat.un.b.vendorUnique = 0; | 2975 | stat.un.b.vendorUnique = 0; |
2982 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 2976 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
2983 | } | 2977 | } |
2984 | 2978 | ||
2985 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 2979 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
@@ -2996,15 +2990,16 @@ lpfc_els_rcv_rpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
2996 | } else { | 2990 | } else { |
2997 | cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t); | 2991 | cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t); |
2998 | } | 2992 | } |
2999 | lpfc_els_rsp_rpl_acc(phba, cmdsize, cmdiocb, ndlp); | 2993 | lpfc_els_rsp_rpl_acc(vport, cmdsize, cmdiocb, ndlp); |
3000 | 2994 | ||
3001 | return 0; | 2995 | return 0; |
3002 | } | 2996 | } |
3003 | 2997 | ||
3004 | static int | 2998 | static int |
3005 | lpfc_els_rcv_farp(struct lpfc_hba * phba, | 2999 | lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3006 | struct lpfc_iocbq * cmdiocb, struct lpfc_nodelist * ndlp) | 3000 | struct lpfc_nodelist *ndlp) |
3007 | { | 3001 | { |
3002 | struct lpfc_hba *phba = vport->phba; | ||
3008 | struct lpfc_dmabuf *pcmd; | 3003 | struct lpfc_dmabuf *pcmd; |
3009 | uint32_t *lp; | 3004 | uint32_t *lp; |
3010 | IOCB_t *icmd; | 3005 | IOCB_t *icmd; |
@@ -3034,14 +3029,14 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, | |||
3034 | cnt = 0; | 3029 | cnt = 0; |
3035 | /* If this FARP command is searching for my portname */ | 3030 | /* If this FARP command is searching for my portname */ |
3036 | if (fp->Mflags & FARP_MATCH_PORT) { | 3031 | if (fp->Mflags & FARP_MATCH_PORT) { |
3037 | if (memcmp(&fp->RportName, &phba->fc_portname, | 3032 | if (memcmp(&fp->RportName, &vport->fc_portname, |
3038 | sizeof (struct lpfc_name)) == 0) | 3033 | sizeof (struct lpfc_name)) == 0) |
3039 | cnt = 1; | 3034 | cnt = 1; |
3040 | } | 3035 | } |
3041 | 3036 | ||
3042 | /* If this FARP command is searching for my nodename */ | 3037 | /* If this FARP command is searching for my nodename */ |
3043 | if (fp->Mflags & FARP_MATCH_NODE) { | 3038 | if (fp->Mflags & FARP_MATCH_NODE) { |
3044 | if (memcmp(&fp->RnodeName, &phba->fc_nodename, | 3039 | if (memcmp(&fp->RnodeName, &vport->fc_nodename, |
3045 | sizeof (struct lpfc_name)) == 0) | 3040 | sizeof (struct lpfc_name)) == 0) |
3046 | cnt = 1; | 3041 | cnt = 1; |
3047 | } | 3042 | } |
@@ -3052,28 +3047,28 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, | |||
3052 | /* Log back into the node before sending the FARP. */ | 3047 | /* Log back into the node before sending the FARP. */ |
3053 | if (fp->Rflags & FARP_REQUEST_PLOGI) { | 3048 | if (fp->Rflags & FARP_REQUEST_PLOGI) { |
3054 | ndlp->nlp_prev_state = ndlp->nlp_state; | 3049 | ndlp->nlp_prev_state = ndlp->nlp_state; |
3055 | lpfc_nlp_set_state(phba, ndlp, | 3050 | lpfc_nlp_set_state(vport, ndlp, |
3056 | NLP_STE_PLOGI_ISSUE); | 3051 | NLP_STE_PLOGI_ISSUE); |
3057 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 3052 | lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); |
3058 | } | 3053 | } |
3059 | 3054 | ||
3060 | /* Send a FARP response to that node */ | 3055 | /* Send a FARP response to that node */ |
3061 | if (fp->Rflags & FARP_REQUEST_FARPR) { | 3056 | if (fp->Rflags & FARP_REQUEST_FARPR) |
3062 | lpfc_issue_els_farpr(phba, did, 0); | 3057 | lpfc_issue_els_farpr(vport, did, 0); |
3063 | } | ||
3064 | } | 3058 | } |
3065 | } | 3059 | } |
3066 | return 0; | 3060 | return 0; |
3067 | } | 3061 | } |
3068 | 3062 | ||
3069 | static int | 3063 | static int |
3070 | lpfc_els_rcv_farpr(struct lpfc_hba * phba, | 3064 | lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3071 | struct lpfc_iocbq * cmdiocb, struct lpfc_nodelist * ndlp) | 3065 | struct lpfc_nodelist *ndlp) |
3072 | { | 3066 | { |
3073 | struct lpfc_dmabuf *pcmd; | 3067 | struct lpfc_dmabuf *pcmd; |
3074 | uint32_t *lp; | 3068 | uint32_t *lp; |
3075 | IOCB_t *icmd; | 3069 | IOCB_t *icmd; |
3076 | uint32_t cmd, did; | 3070 | uint32_t cmd, did; |
3071 | struct lpfc_hba *phba = vport->phba; | ||
3077 | 3072 | ||
3078 | icmd = &cmdiocb->iocb; | 3073 | icmd = &cmdiocb->iocb; |
3079 | did = icmd->un.elsreq64.remoteID; | 3074 | did = icmd->un.elsreq64.remoteID; |
@@ -3089,14 +3084,14 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba, | |||
3089 | phba->brd_no, did); | 3084 | phba->brd_no, did); |
3090 | 3085 | ||
3091 | /* ACCEPT the Farp resp request */ | 3086 | /* ACCEPT the Farp resp request */ |
3092 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 3087 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
3093 | 3088 | ||
3094 | return 0; | 3089 | return 0; |
3095 | } | 3090 | } |
3096 | 3091 | ||
3097 | static int | 3092 | static int |
3098 | lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 3093 | lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3099 | struct lpfc_nodelist * fan_ndlp) | 3094 | struct lpfc_nodelist *fan_ndlp) |
3100 | { | 3095 | { |
3101 | struct lpfc_dmabuf *pcmd; | 3096 | struct lpfc_dmabuf *pcmd; |
3102 | uint32_t *lp; | 3097 | uint32_t *lp; |
@@ -3104,6 +3099,7 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
3104 | uint32_t cmd, did; | 3099 | uint32_t cmd, did; |
3105 | FAN *fp; | 3100 | FAN *fp; |
3106 | struct lpfc_nodelist *ndlp, *next_ndlp; | 3101 | struct lpfc_nodelist *ndlp, *next_ndlp; |
3102 | struct lpfc_hba *phba = vport->phba; | ||
3107 | 3103 | ||
3108 | /* FAN received */ | 3104 | /* FAN received */ |
3109 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0265 FAN received\n", | 3105 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0265 FAN received\n", |
@@ -3119,7 +3115,7 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
3119 | 3115 | ||
3120 | /* FAN received; Fan does not have a reply sequence */ | 3116 | /* FAN received; Fan does not have a reply sequence */ |
3121 | 3117 | ||
3122 | if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { | 3118 | if (phba->pport->port_state == LPFC_LOCAL_CFG_LINK) { |
3123 | if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName, | 3119 | if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName, |
3124 | sizeof(struct lpfc_name)) != 0) || | 3120 | sizeof(struct lpfc_name)) != 0) || |
3125 | (memcmp(&phba->fc_fabparam.portName, &fp->FportName, | 3121 | (memcmp(&phba->fc_fabparam.portName, &fp->FportName, |
@@ -3130,7 +3126,7 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
3130 | */ | 3126 | */ |
3131 | 3127 | ||
3132 | list_for_each_entry_safe(ndlp, next_ndlp, | 3128 | list_for_each_entry_safe(ndlp, next_ndlp, |
3133 | &phba->fc_nodes, nlp_listp) { | 3129 | &vport->fc_nodes, nlp_listp) { |
3134 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) | 3130 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) |
3135 | continue; | 3131 | continue; |
3136 | if (ndlp->nlp_type & NLP_FABRIC) { | 3132 | if (ndlp->nlp_type & NLP_FABRIC) { |
@@ -3138,24 +3134,24 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
3138 | * Clean up old Fabric, Nameserver and | 3134 | * Clean up old Fabric, Nameserver and |
3139 | * other NLP_FABRIC logins | 3135 | * other NLP_FABRIC logins |
3140 | */ | 3136 | */ |
3141 | lpfc_drop_node(phba, ndlp); | 3137 | lpfc_drop_node(vport, ndlp); |
3142 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 3138 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { |
3143 | /* Fail outstanding I/O now since this | 3139 | /* Fail outstanding I/O now since this |
3144 | * device is marked for PLOGI | 3140 | * device is marked for PLOGI |
3145 | */ | 3141 | */ |
3146 | lpfc_unreg_rpi(phba, ndlp); | 3142 | lpfc_unreg_rpi(vport, ndlp); |
3147 | } | 3143 | } |
3148 | } | 3144 | } |
3149 | 3145 | ||
3150 | phba->hba_state = LPFC_FLOGI; | 3146 | vport->port_state = LPFC_FLOGI; |
3151 | lpfc_set_disctmo(phba); | 3147 | lpfc_set_disctmo(vport); |
3152 | lpfc_initial_flogi(phba); | 3148 | lpfc_initial_flogi(vport); |
3153 | return 0; | 3149 | return 0; |
3154 | } | 3150 | } |
3155 | /* Discovery not needed, | 3151 | /* Discovery not needed, |
3156 | * move the nodes to their original state. | 3152 | * move the nodes to their original state. |
3157 | */ | 3153 | */ |
3158 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, | 3154 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, |
3159 | nlp_listp) { | 3155 | nlp_listp) { |
3160 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) | 3156 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) |
3161 | continue; | 3157 | continue; |
@@ -3163,13 +3159,13 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
3163 | switch (ndlp->nlp_prev_state) { | 3159 | switch (ndlp->nlp_prev_state) { |
3164 | case NLP_STE_UNMAPPED_NODE: | 3160 | case NLP_STE_UNMAPPED_NODE: |
3165 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 3161 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
3166 | lpfc_nlp_set_state(phba, ndlp, | 3162 | lpfc_nlp_set_state(vport, ndlp, |
3167 | NLP_STE_UNMAPPED_NODE); | 3163 | NLP_STE_UNMAPPED_NODE); |
3168 | break; | 3164 | break; |
3169 | 3165 | ||
3170 | case NLP_STE_MAPPED_NODE: | 3166 | case NLP_STE_MAPPED_NODE: |
3171 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 3167 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
3172 | lpfc_nlp_set_state(phba, ndlp, | 3168 | lpfc_nlp_set_state(vport, ndlp, |
3173 | NLP_STE_MAPPED_NODE); | 3169 | NLP_STE_MAPPED_NODE); |
3174 | break; | 3170 | break; |
3175 | 3171 | ||
@@ -3179,7 +3175,7 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
3179 | } | 3175 | } |
3180 | 3176 | ||
3181 | /* Start discovery - this should just do CLEAR_LA */ | 3177 | /* Start discovery - this should just do CLEAR_LA */ |
3182 | lpfc_disc_start(phba); | 3178 | lpfc_disc_start(vport); |
3183 | } | 3179 | } |
3184 | return 0; | 3180 | return 0; |
3185 | } | 3181 | } |
@@ -3187,42 +3183,37 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
3187 | void | 3183 | void |
3188 | lpfc_els_timeout(unsigned long ptr) | 3184 | lpfc_els_timeout(unsigned long ptr) |
3189 | { | 3185 | { |
3190 | struct lpfc_hba *phba; | 3186 | struct lpfc_vport *vport = (struct lpfc_vport *) ptr; |
3187 | struct lpfc_hba *phba = vport->phba; | ||
3191 | unsigned long iflag; | 3188 | unsigned long iflag; |
3192 | 3189 | ||
3193 | phba = (struct lpfc_hba *)ptr; | 3190 | spin_lock_irqsave(&vport->work_port_lock, iflag); |
3194 | if (phba == 0) | 3191 | if ((vport->work_port_events & WORKER_ELS_TMO) == 0) { |
3195 | return; | 3192 | vport->work_port_events |= WORKER_ELS_TMO; |
3196 | spin_lock_irqsave(phba->host->host_lock, iflag); | ||
3197 | if (!(phba->work_hba_events & WORKER_ELS_TMO)) { | ||
3198 | phba->work_hba_events |= WORKER_ELS_TMO; | ||
3199 | if (phba->work_wait) | 3193 | if (phba->work_wait) |
3200 | wake_up(phba->work_wait); | 3194 | wake_up(phba->work_wait); |
3201 | } | 3195 | } |
3202 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 3196 | spin_unlock_irqrestore(&vport->work_port_lock, iflag); |
3203 | return; | 3197 | return; |
3204 | } | 3198 | } |
3205 | 3199 | ||
3206 | void | 3200 | void |
3207 | lpfc_els_timeout_handler(struct lpfc_hba *phba) | 3201 | lpfc_els_timeout_handler(struct lpfc_vport *vport) |
3208 | { | 3202 | { |
3203 | struct lpfc_hba *phba = vport->phba; | ||
3209 | struct lpfc_sli_ring *pring; | 3204 | struct lpfc_sli_ring *pring; |
3210 | struct lpfc_iocbq *tmp_iocb, *piocb; | 3205 | struct lpfc_iocbq *tmp_iocb, *piocb; |
3211 | IOCB_t *cmd = NULL; | 3206 | IOCB_t *cmd = NULL; |
3212 | struct lpfc_dmabuf *pcmd; | 3207 | struct lpfc_dmabuf *pcmd; |
3213 | uint32_t *elscmd; | 3208 | uint32_t els_command = 0; |
3214 | uint32_t els_command=0; | ||
3215 | uint32_t timeout; | 3209 | uint32_t timeout; |
3216 | uint32_t remote_ID; | 3210 | uint32_t remote_ID = 0xffffffff; |
3217 | 3211 | ||
3218 | if (phba == 0) | ||
3219 | return; | ||
3220 | spin_lock_irq(phba->host->host_lock); | ||
3221 | /* If the timer is already canceled do nothing */ | 3212 | /* If the timer is already canceled do nothing */ |
3222 | if (!(phba->work_hba_events & WORKER_ELS_TMO)) { | 3213 | if ((vport->work_port_events & WORKER_ELS_TMO) == 0) { |
3223 | spin_unlock_irq(phba->host->host_lock); | ||
3224 | return; | 3214 | return; |
3225 | } | 3215 | } |
3216 | spin_lock_irq(&phba->hbalock); | ||
3226 | timeout = (uint32_t)(phba->fc_ratov << 1); | 3217 | timeout = (uint32_t)(phba->fc_ratov << 1); |
3227 | 3218 | ||
3228 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 3219 | pring = &phba->sli.ring[LPFC_ELS_RING]; |
@@ -3230,16 +3221,17 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
3230 | list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { | 3221 | list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { |
3231 | cmd = &piocb->iocb; | 3222 | cmd = &piocb->iocb; |
3232 | 3223 | ||
3233 | if ((piocb->iocb_flag & LPFC_IO_LIBDFC) || | 3224 | if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 || |
3234 | (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN) || | 3225 | piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || |
3235 | (piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)) { | 3226 | piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN) |
3236 | continue; | 3227 | continue; |
3237 | } | 3228 | |
3229 | if (piocb->vport != vport) | ||
3230 | continue; | ||
3231 | |||
3238 | pcmd = (struct lpfc_dmabuf *) piocb->context2; | 3232 | pcmd = (struct lpfc_dmabuf *) piocb->context2; |
3239 | if (pcmd) { | 3233 | if (pcmd) |
3240 | elscmd = (uint32_t *) (pcmd->virt); | 3234 | els_command = *(uint32_t *) (pcmd->virt); |
3241 | els_command = *elscmd; | ||
3242 | } | ||
3243 | 3235 | ||
3244 | if ((els_command == ELS_CMD_FARP) | 3236 | if ((els_command == ELS_CMD_FARP) |
3245 | || (els_command == ELS_CMD_FARPR)) { | 3237 | || (els_command == ELS_CMD_FARPR)) { |
@@ -3255,12 +3247,14 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
3255 | continue; | 3247 | continue; |
3256 | } | 3248 | } |
3257 | 3249 | ||
3258 | if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { | 3250 | remote_ID = 0xffffffff; |
3259 | struct lpfc_nodelist *ndlp; | 3251 | if (cmd->ulpCommand != CMD_GEN_REQUEST64_CR) |
3260 | ndlp = __lpfc_findnode_rpi(phba, cmd->ulpContext); | ||
3261 | remote_ID = ndlp->nlp_DID; | ||
3262 | } else { | ||
3263 | remote_ID = cmd->un.elsreq64.remoteID; | 3252 | remote_ID = cmd->un.elsreq64.remoteID; |
3253 | else { | ||
3254 | struct lpfc_nodelist *ndlp; | ||
3255 | ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext); | ||
3256 | if (ndlp) | ||
3257 | remote_ID = ndlp->nlp_DID; | ||
3264 | } | 3258 | } |
3265 | 3259 | ||
3266 | lpfc_printf_log(phba, | 3260 | lpfc_printf_log(phba, |
@@ -3272,21 +3266,22 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
3272 | 3266 | ||
3273 | lpfc_sli_issue_abort_iotag(phba, pring, piocb); | 3267 | lpfc_sli_issue_abort_iotag(phba, pring, piocb); |
3274 | } | 3268 | } |
3275 | if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) | 3269 | spin_unlock_irq(&phba->hbalock); |
3276 | mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); | ||
3277 | 3270 | ||
3278 | spin_unlock_irq(phba->host->host_lock); | 3271 | if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) |
3272 | mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); | ||
3279 | } | 3273 | } |
3280 | 3274 | ||
3281 | void | 3275 | void |
3282 | lpfc_els_flush_cmd(struct lpfc_hba *phba) | 3276 | lpfc_els_flush_cmd(struct lpfc_vport *vport) |
3283 | { | 3277 | { |
3284 | LIST_HEAD(completions); | 3278 | LIST_HEAD(completions); |
3279 | struct lpfc_hba *phba = vport->phba; | ||
3285 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; | 3280 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; |
3286 | struct lpfc_iocbq *tmp_iocb, *piocb; | 3281 | struct lpfc_iocbq *tmp_iocb, *piocb; |
3287 | IOCB_t *cmd = NULL; | 3282 | IOCB_t *cmd = NULL; |
3288 | 3283 | ||
3289 | spin_lock_irq(phba->host->host_lock); | 3284 | spin_lock_irq(&phba->hbalock); |
3290 | list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) { | 3285 | list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) { |
3291 | cmd = &piocb->iocb; | 3286 | cmd = &piocb->iocb; |
3292 | 3287 | ||
@@ -3301,61 +3296,63 @@ lpfc_els_flush_cmd(struct lpfc_hba *phba) | |||
3301 | cmd->ulpCommand == CMD_ABORT_XRI_CN) | 3296 | cmd->ulpCommand == CMD_ABORT_XRI_CN) |
3302 | continue; | 3297 | continue; |
3303 | 3298 | ||
3299 | if (piocb->vport != vport) | ||
3300 | continue; | ||
3301 | |||
3304 | list_move_tail(&piocb->list, &completions); | 3302 | list_move_tail(&piocb->list, &completions); |
3305 | pring->txq_cnt--; | 3303 | pring->txq_cnt--; |
3306 | |||
3307 | } | 3304 | } |
3308 | 3305 | ||
3309 | list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { | 3306 | list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { |
3310 | cmd = &piocb->iocb; | ||
3311 | |||
3312 | if (piocb->iocb_flag & LPFC_IO_LIBDFC) { | 3307 | if (piocb->iocb_flag & LPFC_IO_LIBDFC) { |
3313 | continue; | 3308 | continue; |
3314 | } | 3309 | } |
3315 | 3310 | ||
3311 | if (piocb->vport != vport) | ||
3312 | continue; | ||
3313 | |||
3316 | lpfc_sli_issue_abort_iotag(phba, pring, piocb); | 3314 | lpfc_sli_issue_abort_iotag(phba, pring, piocb); |
3317 | } | 3315 | } |
3318 | spin_unlock_irq(phba->host->host_lock); | 3316 | spin_unlock_irq(&phba->hbalock); |
3319 | 3317 | ||
3320 | while(!list_empty(&completions)) { | 3318 | while (!list_empty(&completions)) { |
3321 | piocb = list_get_first(&completions, struct lpfc_iocbq, list); | 3319 | piocb = list_get_first(&completions, struct lpfc_iocbq, list); |
3322 | cmd = &piocb->iocb; | 3320 | cmd = &piocb->iocb; |
3323 | list_del(&piocb->list); | 3321 | list_del(&piocb->list); |
3324 | 3322 | ||
3325 | if (piocb->iocb_cmpl) { | 3323 | if (!piocb->iocb_cmpl) |
3324 | lpfc_sli_release_iocbq(phba, piocb); | ||
3325 | else { | ||
3326 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 3326 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
3327 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | 3327 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
3328 | (piocb->iocb_cmpl) (phba, piocb, piocb); | 3328 | (piocb->iocb_cmpl) (phba, piocb, piocb); |
3329 | } else | 3329 | } |
3330 | lpfc_sli_release_iocbq(phba, piocb); | ||
3331 | } | 3330 | } |
3332 | 3331 | ||
3333 | return; | 3332 | return; |
3334 | } | 3333 | } |
3335 | 3334 | ||
3336 | void | 3335 | void |
3337 | lpfc_els_unsol_event(struct lpfc_hba * phba, | 3336 | lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
3338 | struct lpfc_sli_ring * pring, struct lpfc_iocbq * elsiocb) | 3337 | struct lpfc_iocbq *elsiocb) |
3339 | { | 3338 | { |
3340 | struct lpfc_sli *psli; | 3339 | struct lpfc_sli *psli; |
3341 | struct lpfc_nodelist *ndlp; | 3340 | struct lpfc_nodelist *ndlp; |
3342 | struct lpfc_dmabuf *mp; | 3341 | struct lpfc_dmabuf *mp = NULL; |
3343 | uint32_t *lp; | 3342 | uint32_t *lp; |
3344 | IOCB_t *icmd; | 3343 | IOCB_t *icmd; |
3345 | struct ls_rjt stat; | 3344 | struct ls_rjt stat; |
3346 | uint32_t cmd; | 3345 | uint32_t cmd, did, newnode, rjt_err = 0; |
3347 | uint32_t did; | ||
3348 | uint32_t newnode; | ||
3349 | uint32_t drop_cmd = 0; /* by default do NOT drop received cmd */ | 3346 | uint32_t drop_cmd = 0; /* by default do NOT drop received cmd */ |
3350 | uint32_t rjt_err = 0; | 3347 | struct lpfc_vport *vport = NULL; |
3351 | 3348 | ||
3352 | psli = &phba->sli; | 3349 | psli = &phba->sli; |
3353 | icmd = &elsiocb->iocb; | 3350 | icmd = &elsiocb->iocb; |
3354 | 3351 | ||
3355 | if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) && | 3352 | if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) && |
3356 | ((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) { | 3353 | ((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) { |
3357 | /* Not enough posted buffers; Try posting more buffers */ | ||
3358 | phba->fc_stat.NoRcvBuf++; | 3354 | phba->fc_stat.NoRcvBuf++; |
3355 | /* Not enough posted buffers; Try posting more buffers */ | ||
3359 | lpfc_post_buffer(phba, pring, 0, 1); | 3356 | lpfc_post_buffer(phba, pring, 0, 1); |
3360 | return; | 3357 | return; |
3361 | } | 3358 | } |
@@ -3366,17 +3363,17 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3366 | if (icmd->ulpBdeCount == 0) | 3363 | if (icmd->ulpBdeCount == 0) |
3367 | return; | 3364 | return; |
3368 | 3365 | ||
3369 | /* type of ELS cmd is first 32bit word in packet */ | 3366 | /* type of ELS cmd is first 32bit word in packet */ |
3370 | mp = lpfc_sli_ringpostbuf_get(phba, pring, getPaddr(icmd->un. | 3367 | mp = lpfc_sli_ringpostbuf_get(phba, pring, |
3371 | cont64[0]. | 3368 | getPaddr(icmd->un.cont64[0].addrHigh, |
3372 | addrHigh, | 3369 | icmd->un.cont64[0].addrLow)); |
3373 | icmd->un. | ||
3374 | cont64[0].addrLow)); | ||
3375 | if (mp == 0) { | 3370 | if (mp == 0) { |
3376 | drop_cmd = 1; | 3371 | drop_cmd = 1; |
3377 | goto dropit; | 3372 | goto dropit; |
3378 | } | 3373 | } |
3379 | 3374 | ||
3375 | vport = phba->pport; | ||
3376 | |||
3380 | newnode = 0; | 3377 | newnode = 0; |
3381 | lp = (uint32_t *) mp->virt; | 3378 | lp = (uint32_t *) mp->virt; |
3382 | cmd = *lp++; | 3379 | cmd = *lp++; |
@@ -3390,7 +3387,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3390 | } | 3387 | } |
3391 | 3388 | ||
3392 | /* Check to see if link went down during discovery */ | 3389 | /* Check to see if link went down during discovery */ |
3393 | if (lpfc_els_chk_latt(phba)) { | 3390 | if (lpfc_els_chk_latt(vport)) { |
3394 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 3391 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
3395 | kfree(mp); | 3392 | kfree(mp); |
3396 | drop_cmd = 1; | 3393 | drop_cmd = 1; |
@@ -3398,7 +3395,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3398 | } | 3395 | } |
3399 | 3396 | ||
3400 | did = icmd->un.rcvels.remoteID; | 3397 | did = icmd->un.rcvels.remoteID; |
3401 | ndlp = lpfc_findnode_did(phba, did); | 3398 | ndlp = lpfc_findnode_did(vport, did); |
3402 | if (!ndlp) { | 3399 | if (!ndlp) { |
3403 | /* Cannot find existing Fabric ndlp, so allocate a new one */ | 3400 | /* Cannot find existing Fabric ndlp, so allocate a new one */ |
3404 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | 3401 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
@@ -3409,12 +3406,12 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3409 | goto dropit; | 3406 | goto dropit; |
3410 | } | 3407 | } |
3411 | 3408 | ||
3412 | lpfc_nlp_init(phba, ndlp, did); | 3409 | lpfc_nlp_init(vport, ndlp, did); |
3413 | newnode = 1; | 3410 | newnode = 1; |
3414 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { | 3411 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { |
3415 | ndlp->nlp_type |= NLP_FABRIC; | 3412 | ndlp->nlp_type |= NLP_FABRIC; |
3416 | } | 3413 | } |
3417 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 3414 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
3418 | } | 3415 | } |
3419 | 3416 | ||
3420 | phba->fc_stat.elsRcvFrame++; | 3417 | phba->fc_stat.elsRcvFrame++; |
@@ -3422,6 +3419,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3422 | lpfc_nlp_put(elsiocb->context1); | 3419 | lpfc_nlp_put(elsiocb->context1); |
3423 | elsiocb->context1 = lpfc_nlp_get(ndlp); | 3420 | elsiocb->context1 = lpfc_nlp_get(ndlp); |
3424 | elsiocb->context2 = mp; | 3421 | elsiocb->context2 = mp; |
3422 | elsiocb->vport = vport; | ||
3425 | 3423 | ||
3426 | if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) { | 3424 | if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) { |
3427 | cmd &= ELS_CMD_MASK; | 3425 | cmd &= ELS_CMD_MASK; |
@@ -3429,105 +3427,109 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3429 | /* ELS command <elsCmd> received from NPORT <did> */ | 3427 | /* ELS command <elsCmd> received from NPORT <did> */ |
3430 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 3428 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
3431 | "%d:0112 ELS command x%x received from NPORT x%x " | 3429 | "%d:0112 ELS command x%x received from NPORT x%x " |
3432 | "Data: x%x\n", phba->brd_no, cmd, did, phba->hba_state); | 3430 | "Data: x%x\n", phba->brd_no, cmd, did, |
3431 | vport->port_state); | ||
3433 | 3432 | ||
3434 | switch (cmd) { | 3433 | switch (cmd) { |
3435 | case ELS_CMD_PLOGI: | 3434 | case ELS_CMD_PLOGI: |
3436 | phba->fc_stat.elsRcvPLOGI++; | 3435 | phba->fc_stat.elsRcvPLOGI++; |
3437 | if (phba->hba_state < LPFC_DISC_AUTH) { | 3436 | if (vport->port_state < LPFC_DISC_AUTH) { |
3438 | rjt_err = 1; | 3437 | rjt_err = 1; |
3439 | break; | 3438 | break; |
3440 | } | 3439 | } |
3441 | ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp); | 3440 | ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp); |
3442 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI); | 3441 | lpfc_disc_state_machine(vport, ndlp, elsiocb, |
3442 | NLP_EVT_RCV_PLOGI); | ||
3443 | break; | 3443 | break; |
3444 | case ELS_CMD_FLOGI: | 3444 | case ELS_CMD_FLOGI: |
3445 | phba->fc_stat.elsRcvFLOGI++; | 3445 | phba->fc_stat.elsRcvFLOGI++; |
3446 | lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode); | 3446 | lpfc_els_rcv_flogi(vport, elsiocb, ndlp, newnode); |
3447 | if (newnode) | 3447 | if (newnode) |
3448 | lpfc_drop_node(phba, ndlp); | 3448 | lpfc_drop_node(vport, ndlp); |
3449 | break; | 3449 | break; |
3450 | case ELS_CMD_LOGO: | 3450 | case ELS_CMD_LOGO: |
3451 | phba->fc_stat.elsRcvLOGO++; | 3451 | phba->fc_stat.elsRcvLOGO++; |
3452 | if (phba->hba_state < LPFC_DISC_AUTH) { | 3452 | if (vport->port_state < LPFC_DISC_AUTH) { |
3453 | rjt_err = 1; | 3453 | rjt_err = 1; |
3454 | break; | 3454 | break; |
3455 | } | 3455 | } |
3456 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_LOGO); | 3456 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO); |
3457 | break; | 3457 | break; |
3458 | case ELS_CMD_PRLO: | 3458 | case ELS_CMD_PRLO: |
3459 | phba->fc_stat.elsRcvPRLO++; | 3459 | phba->fc_stat.elsRcvPRLO++; |
3460 | if (phba->hba_state < LPFC_DISC_AUTH) { | 3460 | if (vport->port_state < LPFC_DISC_AUTH) { |
3461 | rjt_err = 1; | 3461 | rjt_err = 1; |
3462 | break; | 3462 | break; |
3463 | } | 3463 | } |
3464 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLO); | 3464 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO); |
3465 | break; | 3465 | break; |
3466 | case ELS_CMD_RSCN: | 3466 | case ELS_CMD_RSCN: |
3467 | phba->fc_stat.elsRcvRSCN++; | 3467 | phba->fc_stat.elsRcvRSCN++; |
3468 | lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode); | 3468 | lpfc_els_rcv_rscn(vport, elsiocb, ndlp, newnode); |
3469 | if (newnode) | 3469 | if (newnode) |
3470 | lpfc_drop_node(phba, ndlp); | 3470 | lpfc_drop_node(vport, ndlp); |
3471 | break; | 3471 | break; |
3472 | case ELS_CMD_ADISC: | 3472 | case ELS_CMD_ADISC: |
3473 | phba->fc_stat.elsRcvADISC++; | 3473 | phba->fc_stat.elsRcvADISC++; |
3474 | if (phba->hba_state < LPFC_DISC_AUTH) { | 3474 | if (vport->port_state < LPFC_DISC_AUTH) { |
3475 | rjt_err = 1; | 3475 | rjt_err = 1; |
3476 | break; | 3476 | break; |
3477 | } | 3477 | } |
3478 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_ADISC); | 3478 | lpfc_disc_state_machine(vport, ndlp, elsiocb, |
3479 | NLP_EVT_RCV_ADISC); | ||
3479 | break; | 3480 | break; |
3480 | case ELS_CMD_PDISC: | 3481 | case ELS_CMD_PDISC: |
3481 | phba->fc_stat.elsRcvPDISC++; | 3482 | phba->fc_stat.elsRcvPDISC++; |
3482 | if (phba->hba_state < LPFC_DISC_AUTH) { | 3483 | if (vport->port_state < LPFC_DISC_AUTH) { |
3483 | rjt_err = 1; | 3484 | rjt_err = 1; |
3484 | break; | 3485 | break; |
3485 | } | 3486 | } |
3486 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PDISC); | 3487 | lpfc_disc_state_machine(vport, ndlp, elsiocb, |
3488 | NLP_EVT_RCV_PDISC); | ||
3487 | break; | 3489 | break; |
3488 | case ELS_CMD_FARPR: | 3490 | case ELS_CMD_FARPR: |
3489 | phba->fc_stat.elsRcvFARPR++; | 3491 | phba->fc_stat.elsRcvFARPR++; |
3490 | lpfc_els_rcv_farpr(phba, elsiocb, ndlp); | 3492 | lpfc_els_rcv_farpr(vport, elsiocb, ndlp); |
3491 | break; | 3493 | break; |
3492 | case ELS_CMD_FARP: | 3494 | case ELS_CMD_FARP: |
3493 | phba->fc_stat.elsRcvFARP++; | 3495 | phba->fc_stat.elsRcvFARP++; |
3494 | lpfc_els_rcv_farp(phba, elsiocb, ndlp); | 3496 | lpfc_els_rcv_farp(vport, elsiocb, ndlp); |
3495 | break; | 3497 | break; |
3496 | case ELS_CMD_FAN: | 3498 | case ELS_CMD_FAN: |
3497 | phba->fc_stat.elsRcvFAN++; | 3499 | phba->fc_stat.elsRcvFAN++; |
3498 | lpfc_els_rcv_fan(phba, elsiocb, ndlp); | 3500 | lpfc_els_rcv_fan(vport, elsiocb, ndlp); |
3499 | break; | 3501 | break; |
3500 | case ELS_CMD_PRLI: | 3502 | case ELS_CMD_PRLI: |
3501 | phba->fc_stat.elsRcvPRLI++; | 3503 | phba->fc_stat.elsRcvPRLI++; |
3502 | if (phba->hba_state < LPFC_DISC_AUTH) { | 3504 | if (vport->port_state < LPFC_DISC_AUTH) { |
3503 | rjt_err = 1; | 3505 | rjt_err = 1; |
3504 | break; | 3506 | break; |
3505 | } | 3507 | } |
3506 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLI); | 3508 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI); |
3507 | break; | 3509 | break; |
3508 | case ELS_CMD_LIRR: | 3510 | case ELS_CMD_LIRR: |
3509 | phba->fc_stat.elsRcvLIRR++; | 3511 | phba->fc_stat.elsRcvLIRR++; |
3510 | lpfc_els_rcv_lirr(phba, elsiocb, ndlp); | 3512 | lpfc_els_rcv_lirr(vport, elsiocb, ndlp); |
3511 | if (newnode) | 3513 | if (newnode) |
3512 | lpfc_drop_node(phba, ndlp); | 3514 | lpfc_drop_node(vport, ndlp); |
3513 | break; | 3515 | break; |
3514 | case ELS_CMD_RPS: | 3516 | case ELS_CMD_RPS: |
3515 | phba->fc_stat.elsRcvRPS++; | 3517 | phba->fc_stat.elsRcvRPS++; |
3516 | lpfc_els_rcv_rps(phba, elsiocb, ndlp); | 3518 | lpfc_els_rcv_rps(vport, elsiocb, ndlp); |
3517 | if (newnode) | 3519 | if (newnode) |
3518 | lpfc_drop_node(phba, ndlp); | 3520 | lpfc_drop_node(vport, ndlp); |
3519 | break; | 3521 | break; |
3520 | case ELS_CMD_RPL: | 3522 | case ELS_CMD_RPL: |
3521 | phba->fc_stat.elsRcvRPL++; | 3523 | phba->fc_stat.elsRcvRPL++; |
3522 | lpfc_els_rcv_rpl(phba, elsiocb, ndlp); | 3524 | lpfc_els_rcv_rpl(vport, elsiocb, ndlp); |
3523 | if (newnode) | 3525 | if (newnode) |
3524 | lpfc_drop_node(phba, ndlp); | 3526 | lpfc_drop_node(vport, ndlp); |
3525 | break; | 3527 | break; |
3526 | case ELS_CMD_RNID: | 3528 | case ELS_CMD_RNID: |
3527 | phba->fc_stat.elsRcvRNID++; | 3529 | phba->fc_stat.elsRcvRNID++; |
3528 | lpfc_els_rcv_rnid(phba, elsiocb, ndlp); | 3530 | lpfc_els_rcv_rnid(vport, elsiocb, ndlp); |
3529 | if (newnode) | 3531 | if (newnode) |
3530 | lpfc_drop_node(phba, ndlp); | 3532 | lpfc_drop_node(vport, ndlp); |
3531 | break; | 3533 | break; |
3532 | default: | 3534 | default: |
3533 | /* Unsupported ELS command, reject */ | 3535 | /* Unsupported ELS command, reject */ |
@@ -3538,7 +3540,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3538 | "%d:0115 Unknown ELS command x%x received from " | 3540 | "%d:0115 Unknown ELS command x%x received from " |
3539 | "NPORT x%x\n", phba->brd_no, cmd, did); | 3541 | "NPORT x%x\n", phba->brd_no, cmd, did); |
3540 | if (newnode) | 3542 | if (newnode) |
3541 | lpfc_drop_node(phba, ndlp); | 3543 | lpfc_drop_node(vport, ndlp); |
3542 | break; | 3544 | break; |
3543 | } | 3545 | } |
3544 | 3546 | ||
@@ -3548,7 +3550,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3548 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 3550 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
3549 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; | 3551 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; |
3550 | stat.un.b.vendorUnique = 0; | 3552 | stat.un.b.vendorUnique = 0; |
3551 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, elsiocb, ndlp); | 3553 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp); |
3552 | } | 3554 | } |
3553 | 3555 | ||
3554 | lpfc_nlp_put(elsiocb->context1); | 3556 | lpfc_nlp_put(elsiocb->context1); |
@@ -3567,5 +3569,4 @@ dropit: | |||
3567 | icmd->ulpTimeout); | 3569 | icmd->ulpTimeout); |
3568 | phba->fc_stat.elsRcvDrop++; | 3570 | phba->fc_stat.elsRcvDrop++; |
3569 | } | 3571 | } |
3570 | return; | ||
3571 | } | 3572 | } |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 61caa8d379e..dee875ee616 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -54,7 +54,7 @@ static uint8_t lpfcAlpaArray[] = { | |||
54 | 0x10, 0x0F, 0x08, 0x04, 0x02, 0x01 | 54 | 0x10, 0x0F, 0x08, 0x04, 0x02, 0x01 |
55 | }; | 55 | }; |
56 | 56 | ||
57 | static void lpfc_disc_timeout_handler(struct lpfc_hba *); | 57 | static void lpfc_disc_timeout_handler(struct lpfc_vport *); |
58 | 58 | ||
59 | void | 59 | void |
60 | lpfc_terminate_rport_io(struct fc_rport *rport) | 60 | lpfc_terminate_rport_io(struct fc_rport *rport) |
@@ -74,14 +74,12 @@ lpfc_terminate_rport_io(struct fc_rport *rport) | |||
74 | return; | 74 | return; |
75 | } | 75 | } |
76 | 76 | ||
77 | phba = ndlp->nlp_phba; | 77 | phba = ndlp->vport->phba; |
78 | 78 | ||
79 | spin_lock_irq(phba->host->host_lock); | ||
80 | if (ndlp->nlp_sid != NLP_NO_SID) { | 79 | if (ndlp->nlp_sid != NLP_NO_SID) { |
81 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], | 80 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], |
82 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); | 81 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); |
83 | } | 82 | } |
84 | spin_unlock_irq(phba->host->host_lock); | ||
85 | 83 | ||
86 | return; | 84 | return; |
87 | } | 85 | } |
@@ -97,6 +95,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
97 | uint8_t *name; | 95 | uint8_t *name; |
98 | int warn_on = 0; | 96 | int warn_on = 0; |
99 | struct lpfc_hba *phba; | 97 | struct lpfc_hba *phba; |
98 | struct lpfc_vport *vport; | ||
100 | 99 | ||
101 | rdata = rport->dd_data; | 100 | rdata = rport->dd_data; |
102 | ndlp = rdata->pnode; | 101 | ndlp = rdata->pnode; |
@@ -113,9 +112,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
113 | return; | 112 | return; |
114 | 113 | ||
115 | name = (uint8_t *)&ndlp->nlp_portname; | 114 | name = (uint8_t *)&ndlp->nlp_portname; |
116 | phba = ndlp->nlp_phba; | 115 | vport = ndlp->vport; |
117 | 116 | phba = vport->phba; | |
118 | spin_lock_irq(phba->host->host_lock); | ||
119 | 117 | ||
120 | if (ndlp->nlp_sid != NLP_NO_SID) { | 118 | if (ndlp->nlp_sid != NLP_NO_SID) { |
121 | warn_on = 1; | 119 | warn_on = 1; |
@@ -123,11 +121,9 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
123 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], | 121 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], |
124 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); | 122 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); |
125 | } | 123 | } |
126 | if (phba->fc_flag & FC_UNLOADING) | 124 | if (vport->load_flag & FC_UNLOADING) |
127 | warn_on = 0; | 125 | warn_on = 0; |
128 | 126 | ||
129 | spin_unlock_irq(phba->host->host_lock); | ||
130 | |||
131 | if (warn_on) { | 127 | if (warn_on) { |
132 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 128 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
133 | "%d:0203 Devloss timeout on " | 129 | "%d:0203 Devloss timeout on " |
@@ -150,11 +146,11 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
150 | ndlp->nlp_state, ndlp->nlp_rpi); | 146 | ndlp->nlp_state, ndlp->nlp_rpi); |
151 | } | 147 | } |
152 | 148 | ||
153 | if (!(phba->fc_flag & FC_UNLOADING) && | 149 | if (!(vport->load_flag & FC_UNLOADING) && |
154 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && | 150 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && |
155 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 151 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
156 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) | 152 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) |
157 | lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM); | 153 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); |
158 | else { | 154 | else { |
159 | rdata->pnode = NULL; | 155 | rdata->pnode = NULL; |
160 | ndlp->rport = NULL; | 156 | ndlp->rport = NULL; |
@@ -166,33 +162,33 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
166 | } | 162 | } |
167 | 163 | ||
168 | static void | 164 | static void |
169 | lpfc_work_list_done(struct lpfc_hba * phba) | 165 | lpfc_work_list_done(struct lpfc_hba *phba) |
170 | { | 166 | { |
171 | struct lpfc_work_evt *evtp = NULL; | 167 | struct lpfc_work_evt *evtp = NULL; |
172 | struct lpfc_nodelist *ndlp; | 168 | struct lpfc_nodelist *ndlp; |
173 | int free_evt; | 169 | int free_evt; |
174 | 170 | ||
175 | spin_lock_irq(phba->host->host_lock); | 171 | spin_lock_irq(&phba->hbalock); |
176 | while(!list_empty(&phba->work_list)) { | 172 | while (!list_empty(&phba->work_list)) { |
177 | list_remove_head((&phba->work_list), evtp, typeof(*evtp), | 173 | list_remove_head((&phba->work_list), evtp, typeof(*evtp), |
178 | evt_listp); | 174 | evt_listp); |
179 | spin_unlock_irq(phba->host->host_lock); | 175 | spin_unlock_irq(&phba->hbalock); |
180 | free_evt = 1; | 176 | free_evt = 1; |
181 | switch (evtp->evt) { | 177 | switch (evtp->evt) { |
182 | case LPFC_EVT_ELS_RETRY: | 178 | case LPFC_EVT_ELS_RETRY: |
183 | ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); | 179 | ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1); |
184 | lpfc_els_retry_delay_handler(ndlp); | 180 | lpfc_els_retry_delay_handler(ndlp); |
185 | free_evt = 0; | 181 | free_evt = 0; |
186 | break; | 182 | break; |
187 | case LPFC_EVT_ONLINE: | 183 | case LPFC_EVT_ONLINE: |
188 | if (phba->hba_state < LPFC_LINK_DOWN) | 184 | if (phba->link_state < LPFC_LINK_DOWN) |
189 | *(int *)(evtp->evt_arg1) = lpfc_online(phba); | 185 | *(int *) (evtp->evt_arg1) = lpfc_online(phba); |
190 | else | 186 | else |
191 | *(int *)(evtp->evt_arg1) = 0; | 187 | *(int *) (evtp->evt_arg1) = 0; |
192 | complete((struct completion *)(evtp->evt_arg2)); | 188 | complete((struct completion *)(evtp->evt_arg2)); |
193 | break; | 189 | break; |
194 | case LPFC_EVT_OFFLINE_PREP: | 190 | case LPFC_EVT_OFFLINE_PREP: |
195 | if (phba->hba_state >= LPFC_LINK_DOWN) | 191 | if (phba->link_state >= LPFC_LINK_DOWN) |
196 | lpfc_offline_prep(phba); | 192 | lpfc_offline_prep(phba); |
197 | *(int *)(evtp->evt_arg1) = 0; | 193 | *(int *)(evtp->evt_arg1) = 0; |
198 | complete((struct completion *)(evtp->evt_arg2)); | 194 | complete((struct completion *)(evtp->evt_arg2)); |
@@ -218,33 +214,32 @@ lpfc_work_list_done(struct lpfc_hba * phba) | |||
218 | case LPFC_EVT_KILL: | 214 | case LPFC_EVT_KILL: |
219 | lpfc_offline(phba); | 215 | lpfc_offline(phba); |
220 | *(int *)(evtp->evt_arg1) | 216 | *(int *)(evtp->evt_arg1) |
221 | = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba); | 217 | = (phba->pport->stopped) |
218 | ? 0 : lpfc_sli_brdkill(phba); | ||
222 | lpfc_unblock_mgmt_io(phba); | 219 | lpfc_unblock_mgmt_io(phba); |
223 | complete((struct completion *)(evtp->evt_arg2)); | 220 | complete((struct completion *)(evtp->evt_arg2)); |
224 | break; | 221 | break; |
225 | } | 222 | } |
226 | if (free_evt) | 223 | if (free_evt) |
227 | kfree(evtp); | 224 | kfree(evtp); |
228 | spin_lock_irq(phba->host->host_lock); | 225 | spin_lock_irq(&phba->hbalock); |
229 | } | 226 | } |
230 | spin_unlock_irq(phba->host->host_lock); | 227 | spin_unlock_irq(&phba->hbalock); |
231 | 228 | ||
232 | } | 229 | } |
233 | 230 | ||
234 | static void | 231 | static void |
235 | lpfc_work_done(struct lpfc_hba * phba) | 232 | lpfc_work_done(struct lpfc_hba *phba) |
236 | { | 233 | { |
237 | struct lpfc_sli_ring *pring; | 234 | struct lpfc_sli_ring *pring; |
238 | int i; | 235 | int i; |
239 | uint32_t ha_copy; | 236 | uint32_t ha_copy, control, work_port_events; |
240 | uint32_t control; | 237 | struct lpfc_vport *vport; |
241 | uint32_t work_hba_events; | ||
242 | 238 | ||
243 | spin_lock_irq(phba->host->host_lock); | 239 | spin_lock_irq(&phba->hbalock); |
244 | ha_copy = phba->work_ha; | 240 | ha_copy = phba->work_ha; |
245 | phba->work_ha = 0; | 241 | phba->work_ha = 0; |
246 | work_hba_events=phba->work_hba_events; | 242 | spin_unlock_irq(&phba->hbalock); |
247 | spin_unlock_irq(phba->host->host_lock); | ||
248 | 243 | ||
249 | if (ha_copy & HA_ERATT) | 244 | if (ha_copy & HA_ERATT) |
250 | lpfc_handle_eratt(phba); | 245 | lpfc_handle_eratt(phba); |
@@ -255,21 +250,25 @@ lpfc_work_done(struct lpfc_hba * phba) | |||
255 | if (ha_copy & HA_LATT) | 250 | if (ha_copy & HA_LATT) |
256 | lpfc_handle_latt(phba); | 251 | lpfc_handle_latt(phba); |
257 | 252 | ||
258 | if (work_hba_events & WORKER_DISC_TMO) | 253 | vport = phba->pport; |
259 | lpfc_disc_timeout_handler(phba); | ||
260 | 254 | ||
261 | if (work_hba_events & WORKER_ELS_TMO) | 255 | work_port_events = vport->work_port_events; |
262 | lpfc_els_timeout_handler(phba); | ||
263 | 256 | ||
264 | if (work_hba_events & WORKER_MBOX_TMO) | 257 | if (work_port_events & WORKER_DISC_TMO) |
258 | lpfc_disc_timeout_handler(vport); | ||
259 | |||
260 | if (work_port_events & WORKER_ELS_TMO) | ||
261 | lpfc_els_timeout_handler(vport); | ||
262 | |||
263 | if (work_port_events & WORKER_MBOX_TMO) | ||
265 | lpfc_mbox_timeout_handler(phba); | 264 | lpfc_mbox_timeout_handler(phba); |
266 | 265 | ||
267 | if (work_hba_events & WORKER_FDMI_TMO) | 266 | if (work_port_events & WORKER_FDMI_TMO) |
268 | lpfc_fdmi_tmo_handler(phba); | 267 | lpfc_fdmi_timeout_handler(vport); |
269 | 268 | ||
270 | spin_lock_irq(phba->host->host_lock); | 269 | spin_lock_irq(&phba->hbalock); |
271 | phba->work_hba_events &= ~work_hba_events; | 270 | vport->work_port_events &= ~work_port_events; |
272 | spin_unlock_irq(phba->host->host_lock); | 271 | spin_unlock_irq(&phba->hbalock); |
273 | 272 | ||
274 | for (i = 0; i < phba->sli.num_rings; i++, ha_copy >>= 4) { | 273 | for (i = 0; i < phba->sli.num_rings; i++, ha_copy >>= 4) { |
275 | pring = &phba->sli.ring[i]; | 274 | pring = &phba->sli.ring[i]; |
@@ -286,33 +285,37 @@ lpfc_work_done(struct lpfc_hba * phba) | |||
286 | /* | 285 | /* |
287 | * Turn on Ring interrupts | 286 | * Turn on Ring interrupts |
288 | */ | 287 | */ |
289 | spin_lock_irq(phba->host->host_lock); | 288 | spin_lock_irq(&phba->hbalock); |
290 | control = readl(phba->HCregaddr); | 289 | control = readl(phba->HCregaddr); |
291 | control |= (HC_R0INT_ENA << i); | 290 | control |= (HC_R0INT_ENA << i); |
292 | writel(control, phba->HCregaddr); | 291 | writel(control, phba->HCregaddr); |
293 | readl(phba->HCregaddr); /* flush */ | 292 | readl(phba->HCregaddr); /* flush */ |
294 | spin_unlock_irq(phba->host->host_lock); | 293 | spin_unlock_irq(&phba->hbalock); |
295 | } | 294 | } |
296 | } | 295 | } |
297 | 296 | ||
298 | lpfc_work_list_done (phba); | 297 | lpfc_work_list_done(phba); |
299 | |||
300 | } | 298 | } |
301 | 299 | ||
302 | static int | 300 | static int |
303 | check_work_wait_done(struct lpfc_hba *phba) { | 301 | check_work_wait_done(struct lpfc_hba *phba) |
302 | { | ||
303 | struct lpfc_vport *vport = phba->pport; | ||
304 | int rc = 0; | ||
305 | |||
306 | |||
307 | if (!vport) | ||
308 | return 0; | ||
309 | spin_lock_irq(&phba->hbalock); | ||
304 | 310 | ||
305 | spin_lock_irq(phba->host->host_lock); | ||
306 | if (phba->work_ha || | 311 | if (phba->work_ha || |
307 | phba->work_hba_events || | 312 | vport->work_port_events || |
308 | (!list_empty(&phba->work_list)) || | 313 | (!list_empty(&phba->work_list)) || |
309 | kthread_should_stop()) { | 314 | kthread_should_stop()) |
310 | spin_unlock_irq(phba->host->host_lock); | 315 | rc = 1; |
311 | return 1; | 316 | |
312 | } else { | 317 | spin_unlock_irq(&phba->hbalock); |
313 | spin_unlock_irq(phba->host->host_lock); | 318 | return rc; |
314 | return 0; | ||
315 | } | ||
316 | } | 319 | } |
317 | 320 | ||
318 | int | 321 | int |
@@ -347,7 +350,7 @@ lpfc_do_work(void *p) | |||
347 | * embedding it in the IOCB. | 350 | * embedding it in the IOCB. |
348 | */ | 351 | */ |
349 | int | 352 | int |
350 | lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2, | 353 | lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2, |
351 | uint32_t evt) | 354 | uint32_t evt) |
352 | { | 355 | { |
353 | struct lpfc_work_evt *evtp; | 356 | struct lpfc_work_evt *evtp; |
@@ -364,11 +367,11 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2, | |||
364 | evtp->evt_arg2 = arg2; | 367 | evtp->evt_arg2 = arg2; |
365 | evtp->evt = evt; | 368 | evtp->evt = evt; |
366 | 369 | ||
367 | spin_lock_irq(phba->host->host_lock); | 370 | spin_lock_irq(&phba->hbalock); |
368 | list_add_tail(&evtp->evt_listp, &phba->work_list); | 371 | list_add_tail(&evtp->evt_listp, &phba->work_list); |
369 | if (phba->work_wait) | 372 | if (phba->work_wait) |
370 | wake_up(phba->work_wait); | 373 | wake_up(phba->work_wait); |
371 | spin_unlock_irq(phba->host->host_lock); | 374 | spin_unlock_irq(&phba->hbalock); |
372 | 375 | ||
373 | return 1; | 376 | return 1; |
374 | } | 377 | } |
@@ -376,75 +379,77 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2, | |||
376 | int | 379 | int |
377 | lpfc_linkdown(struct lpfc_hba *phba) | 380 | lpfc_linkdown(struct lpfc_hba *phba) |
378 | { | 381 | { |
379 | struct lpfc_sli *psli; | 382 | struct lpfc_vport *vport = phba->pport; |
383 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
384 | struct lpfc_sli *psli; | ||
380 | struct lpfc_nodelist *ndlp, *next_ndlp; | 385 | struct lpfc_nodelist *ndlp, *next_ndlp; |
381 | LPFC_MBOXQ_t *mb; | 386 | LPFC_MBOXQ_t *mb; |
382 | int rc; | 387 | int rc; |
383 | 388 | ||
384 | psli = &phba->sli; | 389 | psli = &phba->sli; |
385 | /* sysfs or selective reset may call this routine to clean up */ | 390 | if (phba->link_state == LPFC_LINK_DOWN) { |
386 | if (phba->hba_state >= LPFC_LINK_DOWN) { | 391 | return 0; |
387 | if (phba->hba_state == LPFC_LINK_DOWN) | ||
388 | return 0; | ||
389 | |||
390 | spin_lock_irq(phba->host->host_lock); | ||
391 | phba->hba_state = LPFC_LINK_DOWN; | ||
392 | spin_unlock_irq(phba->host->host_lock); | ||
393 | } | 392 | } |
393 | spin_lock_irq(&phba->hbalock); | ||
394 | if (phba->link_state > LPFC_LINK_DOWN) | ||
395 | phba->link_state = LPFC_LINK_DOWN; | ||
396 | spin_unlock_irq(&phba->hbalock); | ||
394 | 397 | ||
395 | fc_host_post_event(phba->host, fc_get_event_number(), | 398 | fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0); |
396 | FCH_EVT_LINKDOWN, 0); | ||
397 | 399 | ||
398 | /* Clean up any firmware default rpi's */ | 400 | /* Clean up any firmware default rpi's */ |
399 | if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { | 401 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
402 | if (mb) { | ||
400 | lpfc_unreg_did(phba, 0xffffffff, mb); | 403 | lpfc_unreg_did(phba, 0xffffffff, mb); |
401 | mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl; | 404 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
402 | if (lpfc_sli_issue_mbox(phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB)) | 405 | if (lpfc_sli_issue_mbox(phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB)) |
403 | == MBX_NOT_FINISHED) { | 406 | == MBX_NOT_FINISHED) { |
404 | mempool_free( mb, phba->mbox_mem_pool); | 407 | mempool_free(mb, phba->mbox_mem_pool); |
405 | } | 408 | } |
406 | } | 409 | } |
407 | 410 | ||
408 | /* Cleanup any outstanding RSCN activity */ | 411 | /* Cleanup any outstanding RSCN activity */ |
409 | lpfc_els_flush_rscn(phba); | 412 | lpfc_els_flush_rscn(vport); |
410 | 413 | ||
411 | /* Cleanup any outstanding ELS commands */ | 414 | /* Cleanup any outstanding ELS commands */ |
412 | lpfc_els_flush_cmd(phba); | 415 | lpfc_els_flush_cmd(vport); |
413 | 416 | ||
414 | /* | 417 | /* |
415 | * Issue a LINK DOWN event to all nodes. | 418 | * Issue a LINK DOWN event to all nodes. |
416 | */ | 419 | */ |
417 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { | 420 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
418 | /* free any ndlp's on unused list */ | 421 | /* free any ndlp's on unused state */ |
419 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 422 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
420 | lpfc_drop_node(phba, ndlp); | 423 | lpfc_drop_node(vport, ndlp); |
421 | else /* otherwise, force node recovery. */ | 424 | else /* otherwise, force node recovery. */ |
422 | rc = lpfc_disc_state_machine(phba, ndlp, NULL, | 425 | rc = lpfc_disc_state_machine(vport, ndlp, NULL, |
423 | NLP_EVT_DEVICE_RECOVERY); | 426 | NLP_EVT_DEVICE_RECOVERY); |
424 | } | 427 | } |
425 | 428 | ||
426 | /* Setup myDID for link up if we are in pt2pt mode */ | 429 | /* Setup myDID for link up if we are in pt2pt mode */ |
427 | if (phba->fc_flag & FC_PT2PT) { | 430 | if (vport->fc_flag & FC_PT2PT) { |
428 | phba->fc_myDID = 0; | 431 | vport->fc_myDID = 0; |
429 | if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { | 432 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
433 | if (mb) { | ||
430 | lpfc_config_link(phba, mb); | 434 | lpfc_config_link(phba, mb); |
431 | mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl; | 435 | mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl; |
432 | if (lpfc_sli_issue_mbox | 436 | if (lpfc_sli_issue_mbox(phba, mb, |
433 | (phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB)) | 437 | (MBX_NOWAIT | MBX_STOP_IOCB)) |
434 | == MBX_NOT_FINISHED) { | 438 | == MBX_NOT_FINISHED) { |
435 | mempool_free( mb, phba->mbox_mem_pool); | 439 | mempool_free(mb, phba->mbox_mem_pool); |
436 | } | 440 | } |
437 | } | 441 | } |
438 | spin_lock_irq(phba->host->host_lock); | 442 | spin_lock_irq(shost->host_lock); |
439 | phba->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI); | 443 | vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI); |
440 | spin_unlock_irq(phba->host->host_lock); | 444 | spin_unlock_irq(shost->host_lock); |
441 | } | 445 | } |
442 | spin_lock_irq(phba->host->host_lock); | 446 | |
443 | phba->fc_flag &= ~FC_LBIT; | 447 | spin_lock_irq(shost->host_lock); |
444 | spin_unlock_irq(phba->host->host_lock); | 448 | vport->fc_flag &= ~FC_LBIT; |
449 | spin_unlock_irq(shost->host_lock); | ||
445 | 450 | ||
446 | /* Turn off discovery timer if its running */ | 451 | /* Turn off discovery timer if its running */ |
447 | lpfc_can_disctmo(phba); | 452 | lpfc_can_disctmo(vport); |
448 | 453 | ||
449 | /* Must process IOCBs on all rings to handle ABORTed I/Os */ | 454 | /* Must process IOCBs on all rings to handle ABORTed I/Os */ |
450 | return 0; | 455 | return 0; |
@@ -453,46 +458,47 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
453 | static int | 458 | static int |
454 | lpfc_linkup(struct lpfc_hba *phba) | 459 | lpfc_linkup(struct lpfc_hba *phba) |
455 | { | 460 | { |
461 | struct lpfc_vport *vport = phba->pport; | ||
462 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
456 | struct lpfc_nodelist *ndlp, *next_ndlp; | 463 | struct lpfc_nodelist *ndlp, *next_ndlp; |
457 | 464 | ||
458 | fc_host_post_event(phba->host, fc_get_event_number(), | 465 | fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKUP, 0); |
459 | FCH_EVT_LINKUP, 0); | ||
460 | 466 | ||
461 | spin_lock_irq(phba->host->host_lock); | 467 | spin_lock_irq(shost->host_lock); |
462 | phba->hba_state = LPFC_LINK_UP; | 468 | phba->link_state = LPFC_LINK_UP; |
463 | phba->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY | | 469 | vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY | |
464 | FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY); | 470 | FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY); |
465 | phba->fc_flag |= FC_NDISC_ACTIVE; | 471 | vport->fc_flag |= FC_NDISC_ACTIVE; |
466 | phba->fc_ns_retry = 0; | 472 | vport->fc_ns_retry = 0; |
467 | spin_unlock_irq(phba->host->host_lock); | 473 | spin_unlock_irq(shost->host_lock); |
468 | 474 | ||
469 | 475 | ||
470 | if (phba->fc_flag & FC_LBIT) { | 476 | if (vport->fc_flag & FC_LBIT) { |
471 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { | 477 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
472 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) { | 478 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) { |
473 | if (ndlp->nlp_type & NLP_FABRIC) { | 479 | if (ndlp->nlp_type & NLP_FABRIC) { |
474 | /* | 480 | /* |
475 | * On Linkup its safe to clean up the | 481 | * On Linkup its safe to clean up the |
476 | * ndlp from Fabric connections. | 482 | * ndlp from Fabric connections. |
477 | */ | 483 | */ |
478 | lpfc_nlp_set_state(phba, ndlp, | 484 | lpfc_nlp_set_state(vport, ndlp, |
479 | NLP_STE_UNUSED_NODE); | 485 | NLP_STE_UNUSED_NODE); |
480 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 486 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { |
481 | /* | 487 | /* |
482 | * Fail outstanding IO now since | 488 | * Fail outstanding IO now since |
483 | * device is marked for PLOGI. | 489 | * device is marked for PLOGI. |
484 | */ | 490 | */ |
485 | lpfc_unreg_rpi(phba, ndlp); | 491 | lpfc_unreg_rpi(vport, ndlp); |
486 | } | 492 | } |
487 | } | 493 | } |
488 | } | 494 | } |
489 | } | 495 | } |
490 | 496 | ||
491 | /* free any ndlp's on unused list */ | 497 | /* free any ndlp's in unused state */ |
492 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, | 498 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, |
493 | nlp_listp) { | 499 | nlp_listp) { |
494 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 500 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
495 | lpfc_drop_node(phba, ndlp); | 501 | lpfc_drop_node(vport, ndlp); |
496 | } | 502 | } |
497 | 503 | ||
498 | return 0; | 504 | return 0; |
@@ -505,14 +511,14 @@ lpfc_linkup(struct lpfc_hba *phba) | |||
505 | * handed off to the SLI layer. | 511 | * handed off to the SLI layer. |
506 | */ | 512 | */ |
507 | void | 513 | void |
508 | lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 514 | lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
509 | { | 515 | { |
510 | struct lpfc_sli *psli; | 516 | struct lpfc_vport *vport = pmb->vport; |
511 | MAILBOX_t *mb; | 517 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
518 | struct lpfc_sli *psli = &phba->sli; | ||
519 | MAILBOX_t *mb = &pmb->mb; | ||
512 | uint32_t control; | 520 | uint32_t control; |
513 | 521 | ||
514 | psli = &phba->sli; | ||
515 | mb = &pmb->mb; | ||
516 | /* Since we don't do discovery right now, turn these off here */ | 522 | /* Since we don't do discovery right now, turn these off here */ |
517 | psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT; | 523 | psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT; |
518 | psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT; | 524 | psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT; |
@@ -520,32 +526,33 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
520 | 526 | ||
521 | /* Check for error */ | 527 | /* Check for error */ |
522 | if ((mb->mbxStatus) && (mb->mbxStatus != 0x1601)) { | 528 | if ((mb->mbxStatus) && (mb->mbxStatus != 0x1601)) { |
523 | /* CLEAR_LA mbox error <mbxStatus> state <hba_state> */ | 529 | /* CLEAR_LA mbox error <mbxStatus> state <port_state> */ |
524 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | 530 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
525 | "%d:0320 CLEAR_LA mbxStatus error x%x hba " | 531 | "%d:0320 CLEAR_LA mbxStatus error x%x hba " |
526 | "state x%x\n", | 532 | "state x%x\n", |
527 | phba->brd_no, mb->mbxStatus, phba->hba_state); | 533 | phba->brd_no, mb->mbxStatus, vport->port_state); |
528 | 534 | ||
529 | phba->hba_state = LPFC_HBA_ERROR; | 535 | phba->link_state = LPFC_HBA_ERROR; |
530 | goto out; | 536 | goto out; |
531 | } | 537 | } |
532 | 538 | ||
533 | if (phba->fc_flag & FC_ABORT_DISCOVERY) | 539 | if (vport->fc_flag & FC_ABORT_DISCOVERY) |
534 | goto out; | 540 | goto out; |
535 | 541 | ||
536 | phba->num_disc_nodes = 0; | 542 | vport->num_disc_nodes = 0; |
537 | /* go thru NPR list and issue ELS PLOGIs */ | 543 | /* go thru NPR nodes and issue ELS PLOGIs */ |
538 | if (phba->fc_npr_cnt) { | 544 | if (vport->fc_npr_cnt) |
539 | lpfc_els_disc_plogi(phba); | 545 | lpfc_els_disc_plogi(vport); |
540 | } | ||
541 | 546 | ||
542 | if (!phba->num_disc_nodes) { | 547 | if (!vport->num_disc_nodes) { |
543 | spin_lock_irq(phba->host->host_lock); | 548 | spin_lock_irq(shost->host_lock); |
544 | phba->fc_flag &= ~FC_NDISC_ACTIVE; | 549 | vport->fc_flag &= ~FC_NDISC_ACTIVE; |
545 | spin_unlock_irq(phba->host->host_lock); | 550 | spin_unlock_irq(shost->host_lock); |
546 | } | 551 | } |
547 | 552 | ||
548 | phba->hba_state = LPFC_HBA_READY; | 553 | printk(KERN_ERR "%s (%d): vport ready\n", |
554 | __FUNCTION__, __LINE__); | ||
555 | vport->port_state = LPFC_VPORT_READY; | ||
549 | 556 | ||
550 | out: | 557 | out: |
551 | /* Device Discovery completes */ | 558 | /* Device Discovery completes */ |
@@ -555,34 +562,34 @@ out: | |||
555 | "%d:0225 Device Discovery completes\n", | 562 | "%d:0225 Device Discovery completes\n", |
556 | phba->brd_no); | 563 | phba->brd_no); |
557 | 564 | ||
558 | mempool_free( pmb, phba->mbox_mem_pool); | 565 | mempool_free(pmb, phba->mbox_mem_pool); |
559 | 566 | ||
560 | spin_lock_irq(phba->host->host_lock); | 567 | spin_lock_irq(shost->host_lock); |
561 | phba->fc_flag &= ~FC_ABORT_DISCOVERY; | 568 | vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK); |
562 | if (phba->fc_flag & FC_ESTABLISH_LINK) { | 569 | spin_unlock_irq(shost->host_lock); |
563 | phba->fc_flag &= ~FC_ESTABLISH_LINK; | ||
564 | } | ||
565 | spin_unlock_irq(phba->host->host_lock); | ||
566 | 570 | ||
567 | del_timer_sync(&phba->fc_estabtmo); | 571 | del_timer_sync(&phba->fc_estabtmo); |
568 | 572 | ||
569 | lpfc_can_disctmo(phba); | 573 | lpfc_can_disctmo(vport); |
570 | 574 | ||
571 | /* turn on Link Attention interrupts */ | 575 | /* turn on Link Attention interrupts */ |
572 | spin_lock_irq(phba->host->host_lock); | 576 | |
577 | spin_lock_irq(&phba->hbalock); | ||
573 | psli->sli_flag |= LPFC_PROCESS_LA; | 578 | psli->sli_flag |= LPFC_PROCESS_LA; |
574 | control = readl(phba->HCregaddr); | 579 | control = readl(phba->HCregaddr); |
575 | control |= HC_LAINT_ENA; | 580 | control |= HC_LAINT_ENA; |
576 | writel(control, phba->HCregaddr); | 581 | writel(control, phba->HCregaddr); |
577 | readl(phba->HCregaddr); /* flush */ | 582 | readl(phba->HCregaddr); /* flush */ |
578 | spin_unlock_irq(phba->host->host_lock); | 583 | spin_unlock_irq(&phba->hbalock); |
579 | 584 | ||
580 | return; | 585 | return; |
581 | } | 586 | } |
582 | 587 | ||
588 | |||
583 | static void | 589 | static void |
584 | lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 590 | lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
585 | { | 591 | { |
592 | struct lpfc_vport *vport = pmb->vport; | ||
586 | struct lpfc_sli *psli = &phba->sli; | 593 | struct lpfc_sli *psli = &phba->sli; |
587 | int rc; | 594 | int rc; |
588 | 595 | ||
@@ -592,58 +599,64 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
592 | mempool_free(pmb, phba->mbox_mem_pool); | 599 | mempool_free(pmb, phba->mbox_mem_pool); |
593 | 600 | ||
594 | if (phba->fc_topology == TOPOLOGY_LOOP && | 601 | if (phba->fc_topology == TOPOLOGY_LOOP && |
595 | phba->fc_flag & FC_PUBLIC_LOOP && | 602 | vport->fc_flag & FC_PUBLIC_LOOP && |
596 | !(phba->fc_flag & FC_LBIT)) { | 603 | !(vport->fc_flag & FC_LBIT)) { |
597 | /* Need to wait for FAN - use discovery timer | 604 | /* Need to wait for FAN - use discovery timer |
598 | * for timeout. hba_state is identically | 605 | * for timeout. port_state is identically |
599 | * LPFC_LOCAL_CFG_LINK while waiting for FAN | 606 | * LPFC_LOCAL_CFG_LINK while waiting for FAN |
600 | */ | 607 | */ |
601 | lpfc_set_disctmo(phba); | 608 | lpfc_set_disctmo(vport); |
602 | return; | 609 | return; |
603 | } | 610 | } |
604 | 611 | ||
605 | /* Start discovery by sending a FLOGI. hba_state is identically | 612 | /* Start discovery by sending a FLOGI. port_state is identically |
606 | * LPFC_FLOGI while waiting for FLOGI cmpl | 613 | * LPFC_FLOGI while waiting for FLOGI cmpl |
607 | */ | 614 | */ |
608 | phba->hba_state = LPFC_FLOGI; | 615 | vport->port_state = LPFC_FLOGI; |
609 | lpfc_set_disctmo(phba); | 616 | lpfc_set_disctmo(vport); |
610 | lpfc_initial_flogi(phba); | 617 | lpfc_initial_flogi(vport); |
611 | return; | 618 | return; |
612 | 619 | ||
613 | out: | 620 | out: |
614 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | 621 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
615 | "%d:0306 CONFIG_LINK mbxStatus error x%x " | 622 | "%d:0306 CONFIG_LINK mbxStatus error x%x " |
616 | "HBA state x%x\n", | 623 | "HBA state x%x\n", |
617 | phba->brd_no, pmb->mb.mbxStatus, phba->hba_state); | 624 | phba->brd_no, pmb->mb.mbxStatus, vport->port_state); |
618 | 625 | ||
619 | lpfc_linkdown(phba); | 626 | lpfc_linkdown(phba); |
620 | 627 | ||
621 | phba->hba_state = LPFC_HBA_ERROR; | 628 | phba->link_state = LPFC_HBA_ERROR; |
622 | 629 | ||
623 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 630 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
624 | "%d:0200 CONFIG_LINK bad hba state x%x\n", | 631 | "%d:0200 CONFIG_LINK bad hba state x%x\n", |
625 | phba->brd_no, phba->hba_state); | 632 | phba->brd_no, vport->port_state); |
626 | 633 | ||
627 | lpfc_clear_la(phba, pmb); | 634 | lpfc_clear_la(phba, pmb); |
635 | printk(KERN_ERR "%s (%d): do clear_la\n", | ||
636 | __FUNCTION__, __LINE__); | ||
628 | pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 637 | pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
638 | pmb->vport = vport; | ||
629 | rc = lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); | 639 | rc = lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); |
630 | if (rc == MBX_NOT_FINISHED) { | 640 | if (rc == MBX_NOT_FINISHED) { |
631 | mempool_free(pmb, phba->mbox_mem_pool); | 641 | mempool_free(pmb, phba->mbox_mem_pool); |
632 | lpfc_disc_flush_list(phba); | 642 | lpfc_disc_flush_list(vport); |
633 | psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 643 | psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
634 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 644 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
635 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 645 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
636 | phba->hba_state = LPFC_HBA_READY; | 646 | printk(KERN_ERR "%s (%d): vport ready\n", |
647 | __FUNCTION__, __LINE__); | ||
648 | vport->port_state = LPFC_VPORT_READY; | ||
637 | } | 649 | } |
638 | return; | 650 | return; |
639 | } | 651 | } |
640 | 652 | ||
641 | static void | 653 | static void |
642 | lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 654 | lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
643 | { | 655 | { |
644 | struct lpfc_sli *psli = &phba->sli; | 656 | struct lpfc_sli *psli = &phba->sli; |
645 | MAILBOX_t *mb = &pmb->mb; | 657 | MAILBOX_t *mb = &pmb->mb; |
646 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; | 658 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; |
659 | struct lpfc_vport *vport = pmb->vport; | ||
647 | 660 | ||
648 | 661 | ||
649 | /* Check for error */ | 662 | /* Check for error */ |
@@ -652,67 +665,78 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
652 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | 665 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
653 | "%d:0319 READ_SPARAM mbxStatus error x%x " | 666 | "%d:0319 READ_SPARAM mbxStatus error x%x " |
654 | "hba state x%x>\n", | 667 | "hba state x%x>\n", |
655 | phba->brd_no, mb->mbxStatus, phba->hba_state); | 668 | phba->brd_no, mb->mbxStatus, vport->port_state); |
656 | 669 | ||
657 | lpfc_linkdown(phba); | 670 | lpfc_linkdown(phba); |
658 | phba->hba_state = LPFC_HBA_ERROR; | 671 | phba->link_state = LPFC_HBA_ERROR; |
659 | goto out; | 672 | goto out; |
660 | } | 673 | } |
661 | 674 | ||
662 | memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt, | 675 | memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt, |
663 | sizeof (struct serv_parm)); | 676 | sizeof (struct serv_parm)); |
664 | if (phba->cfg_soft_wwnn) | 677 | if (phba->cfg_soft_wwnn) |
665 | u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn); | 678 | u64_to_wwn(phba->cfg_soft_wwnn, |
679 | vport->fc_sparam.nodeName.u.wwn); | ||
666 | if (phba->cfg_soft_wwpn) | 680 | if (phba->cfg_soft_wwpn) |
667 | u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn); | 681 | u64_to_wwn(phba->cfg_soft_wwpn, |
668 | memcpy((uint8_t *) & phba->fc_nodename, | 682 | vport->fc_sparam.portName.u.wwn); |
669 | (uint8_t *) & phba->fc_sparam.nodeName, | 683 | memcpy((uint8_t *) &vport->fc_nodename, |
684 | (uint8_t *) &vport->fc_sparam.nodeName, | ||
670 | sizeof (struct lpfc_name)); | 685 | sizeof (struct lpfc_name)); |
671 | memcpy((uint8_t *) & phba->fc_portname, | 686 | memcpy((uint8_t *) &vport->fc_portname, |
672 | (uint8_t *) & phba->fc_sparam.portName, | 687 | (uint8_t *) &vport->fc_sparam.portName, |
673 | sizeof (struct lpfc_name)); | 688 | sizeof (struct lpfc_name)); |
674 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 689 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
675 | kfree(mp); | 690 | kfree(mp); |
676 | mempool_free( pmb, phba->mbox_mem_pool); | 691 | mempool_free(pmb, phba->mbox_mem_pool); |
677 | return; | 692 | return; |
678 | 693 | ||
679 | out: | 694 | out: |
680 | pmb->context1 = NULL; | 695 | pmb->context1 = NULL; |
681 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 696 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
682 | kfree(mp); | 697 | kfree(mp); |
683 | if (phba->hba_state != LPFC_CLEAR_LA) { | 698 | if (phba->link_state != LPFC_CLEAR_LA) { |
699 | struct lpfc_sli_ring *extra_ring = | ||
700 | &psli->ring[psli->extra_ring]; | ||
701 | struct lpfc_sli_ring *fcp_ring = &psli->ring[psli->fcp_ring]; | ||
702 | struct lpfc_sli_ring *next_ring = &psli->ring[psli->next_ring]; | ||
703 | |||
684 | lpfc_clear_la(phba, pmb); | 704 | lpfc_clear_la(phba, pmb); |
705 | printk(KERN_ERR "%s (%d): do clear_la\n", | ||
706 | __FUNCTION__, __LINE__); | ||
685 | pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 707 | pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
708 | pmb->vport = vport; | ||
686 | if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)) | 709 | if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)) |
687 | == MBX_NOT_FINISHED) { | 710 | == MBX_NOT_FINISHED) { |
688 | mempool_free( pmb, phba->mbox_mem_pool); | 711 | mempool_free(pmb, phba->mbox_mem_pool); |
689 | lpfc_disc_flush_list(phba); | 712 | lpfc_disc_flush_list(vport); |
690 | psli->ring[(psli->extra_ring)].flag &= | 713 | extra_ring->flag &= ~LPFC_STOP_IOCB_EVENT; |
691 | ~LPFC_STOP_IOCB_EVENT; | 714 | fcp_ring->flag &= ~LPFC_STOP_IOCB_EVENT; |
692 | psli->ring[(psli->fcp_ring)].flag &= | 715 | next_ring->flag &= ~LPFC_STOP_IOCB_EVENT; |
693 | ~LPFC_STOP_IOCB_EVENT; | 716 | printk(KERN_ERR "%s (%d): vport ready\n", |
694 | psli->ring[(psli->next_ring)].flag &= | 717 | __FUNCTION__, __LINE__); |
695 | ~LPFC_STOP_IOCB_EVENT; | 718 | vport->port_state = LPFC_VPORT_READY; |
696 | phba->hba_state = LPFC_HBA_READY; | ||
697 | } | 719 | } |
698 | } else { | 720 | } else { |
699 | mempool_free( pmb, phba->mbox_mem_pool); | 721 | mempool_free(pmb, phba->mbox_mem_pool); |
700 | } | 722 | } |
701 | return; | 723 | return; |
702 | } | 724 | } |
703 | 725 | ||
704 | static void | 726 | static void |
705 | lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | 727 | lpfc_mbx_process_link_up(struct lpfc_vport *vport, READ_LA_VAR *la) |
706 | { | 728 | { |
707 | int i; | 729 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
730 | struct lpfc_hba *phba = vport->phba; | ||
708 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox; | 731 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox; |
732 | int i; | ||
709 | struct lpfc_dmabuf *mp; | 733 | struct lpfc_dmabuf *mp; |
710 | int rc; | 734 | int rc; |
711 | 735 | ||
712 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 736 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
713 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 737 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
714 | 738 | ||
715 | spin_lock_irq(phba->host->host_lock); | 739 | spin_lock_irq(shost->host_lock); |
716 | switch (la->UlnkSpeed) { | 740 | switch (la->UlnkSpeed) { |
717 | case LA_1GHZ_LINK: | 741 | case LA_1GHZ_LINK: |
718 | phba->fc_linkspeed = LA_1GHZ_LINK; | 742 | phba->fc_linkspeed = LA_1GHZ_LINK; |
@@ -737,9 +761,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
737 | /* Get Loop Map information */ | 761 | /* Get Loop Map information */ |
738 | 762 | ||
739 | if (la->il) | 763 | if (la->il) |
740 | phba->fc_flag |= FC_LBIT; | 764 | vport->fc_flag |= FC_LBIT; |
741 | 765 | ||
742 | phba->fc_myDID = la->granted_AL_PA; | 766 | vport->fc_myDID = la->granted_AL_PA; |
743 | i = la->un.lilpBde64.tus.f.bdeSize; | 767 | i = la->un.lilpBde64.tus.f.bdeSize; |
744 | 768 | ||
745 | if (i == 0) { | 769 | if (i == 0) { |
@@ -781,14 +805,15 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
781 | } | 805 | } |
782 | } | 806 | } |
783 | } else { | 807 | } else { |
784 | phba->fc_myDID = phba->fc_pref_DID; | 808 | vport->fc_myDID = phba->fc_pref_DID; |
785 | phba->fc_flag |= FC_LBIT; | 809 | vport->fc_flag |= FC_LBIT; |
786 | } | 810 | } |
787 | spin_unlock_irq(phba->host->host_lock); | 811 | spin_unlock_irq(shost->host_lock); |
788 | 812 | ||
789 | lpfc_linkup(phba); | 813 | lpfc_linkup(phba); |
790 | if (sparam_mbox) { | 814 | if (sparam_mbox) { |
791 | lpfc_read_sparam(phba, sparam_mbox); | 815 | lpfc_read_sparam(phba, sparam_mbox); |
816 | sparam_mbox->vport = vport; | ||
792 | sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; | 817 | sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; |
793 | rc = lpfc_sli_issue_mbox(phba, sparam_mbox, | 818 | rc = lpfc_sli_issue_mbox(phba, sparam_mbox, |
794 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 819 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
@@ -804,8 +829,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
804 | } | 829 | } |
805 | 830 | ||
806 | if (cfglink_mbox) { | 831 | if (cfglink_mbox) { |
807 | phba->hba_state = LPFC_LOCAL_CFG_LINK; | 832 | vport->port_state = LPFC_LOCAL_CFG_LINK; |
808 | lpfc_config_link(phba, cfglink_mbox); | 833 | lpfc_config_link(phba, cfglink_mbox); |
834 | cfglink_mbox->vport = vport; | ||
809 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; | 835 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; |
810 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, | 836 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, |
811 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 837 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
@@ -815,20 +841,21 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
815 | } | 841 | } |
816 | 842 | ||
817 | static void | 843 | static void |
818 | lpfc_mbx_issue_link_down(struct lpfc_hba *phba) { | 844 | lpfc_mbx_issue_link_down(struct lpfc_hba *phba) |
845 | { | ||
819 | uint32_t control; | 846 | uint32_t control; |
820 | struct lpfc_sli *psli = &phba->sli; | 847 | struct lpfc_sli *psli = &phba->sli; |
821 | 848 | ||
822 | lpfc_linkdown(phba); | 849 | lpfc_linkdown(phba); |
823 | 850 | ||
824 | /* turn on Link Attention interrupts - no CLEAR_LA needed */ | 851 | /* turn on Link Attention interrupts - no CLEAR_LA needed */ |
825 | spin_lock_irq(phba->host->host_lock); | 852 | spin_lock_irq(&phba->hbalock); |
826 | psli->sli_flag |= LPFC_PROCESS_LA; | 853 | psli->sli_flag |= LPFC_PROCESS_LA; |
827 | control = readl(phba->HCregaddr); | 854 | control = readl(phba->HCregaddr); |
828 | control |= HC_LAINT_ENA; | 855 | control |= HC_LAINT_ENA; |
829 | writel(control, phba->HCregaddr); | 856 | writel(control, phba->HCregaddr); |
830 | readl(phba->HCregaddr); /* flush */ | 857 | readl(phba->HCregaddr); /* flush */ |
831 | spin_unlock_irq(phba->host->host_lock); | 858 | spin_unlock_irq(&phba->hbalock); |
832 | } | 859 | } |
833 | 860 | ||
834 | /* | 861 | /* |
@@ -838,8 +865,10 @@ lpfc_mbx_issue_link_down(struct lpfc_hba *phba) { | |||
838 | * handed off to the SLI layer. | 865 | * handed off to the SLI layer. |
839 | */ | 866 | */ |
840 | void | 867 | void |
841 | lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 868 | lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
842 | { | 869 | { |
870 | struct lpfc_vport *vport = pmb->vport; | ||
871 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
843 | READ_LA_VAR *la; | 872 | READ_LA_VAR *la; |
844 | MAILBOX_t *mb = &pmb->mb; | 873 | MAILBOX_t *mb = &pmb->mb; |
845 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 874 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
@@ -851,9 +880,9 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
851 | LOG_LINK_EVENT, | 880 | LOG_LINK_EVENT, |
852 | "%d:1307 READ_LA mbox error x%x state x%x\n", | 881 | "%d:1307 READ_LA mbox error x%x state x%x\n", |
853 | phba->brd_no, | 882 | phba->brd_no, |
854 | mb->mbxStatus, phba->hba_state); | 883 | mb->mbxStatus, vport->port_state); |
855 | lpfc_mbx_issue_link_down(phba); | 884 | lpfc_mbx_issue_link_down(phba); |
856 | phba->hba_state = LPFC_HBA_ERROR; | 885 | phba->link_state = LPFC_HBA_ERROR; |
857 | goto lpfc_mbx_cmpl_read_la_free_mbuf; | 886 | goto lpfc_mbx_cmpl_read_la_free_mbuf; |
858 | } | 887 | } |
859 | 888 | ||
@@ -861,27 +890,26 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
861 | 890 | ||
862 | memcpy(&phba->alpa_map[0], mp->virt, 128); | 891 | memcpy(&phba->alpa_map[0], mp->virt, 128); |
863 | 892 | ||
864 | spin_lock_irq(phba->host->host_lock); | 893 | spin_lock_irq(shost->host_lock); |
865 | if (la->pb) | 894 | if (la->pb) |
866 | phba->fc_flag |= FC_BYPASSED_MODE; | 895 | vport->fc_flag |= FC_BYPASSED_MODE; |
867 | else | 896 | else |
868 | phba->fc_flag &= ~FC_BYPASSED_MODE; | 897 | vport->fc_flag &= ~FC_BYPASSED_MODE; |
869 | spin_unlock_irq(phba->host->host_lock); | 898 | spin_unlock_irq(shost->host_lock); |
870 | 899 | ||
871 | if (((phba->fc_eventTag + 1) < la->eventTag) || | 900 | if (((phba->fc_eventTag + 1) < la->eventTag) || |
872 | (phba->fc_eventTag == la->eventTag)) { | 901 | (phba->fc_eventTag == la->eventTag)) { |
873 | phba->fc_stat.LinkMultiEvent++; | 902 | phba->fc_stat.LinkMultiEvent++; |
874 | if (la->attType == AT_LINK_UP) { | 903 | if (la->attType == AT_LINK_UP) |
875 | if (phba->fc_eventTag != 0) | 904 | if (phba->fc_eventTag != 0) |
876 | lpfc_linkdown(phba); | 905 | lpfc_linkdown(phba); |
877 | } | 906 | } |
878 | } | ||
879 | 907 | ||
880 | phba->fc_eventTag = la->eventTag; | 908 | phba->fc_eventTag = la->eventTag; |
881 | 909 | ||
882 | if (la->attType == AT_LINK_UP) { | 910 | if (la->attType == AT_LINK_UP) { |
883 | phba->fc_stat.LinkUp++; | 911 | phba->fc_stat.LinkUp++; |
884 | if (phba->fc_flag & FC_LOOPBACK_MODE) { | 912 | if (phba->link_flag & LS_LOOPBACK_MODE) { |
885 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, | 913 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, |
886 | "%d:1306 Link Up Event in loop back mode " | 914 | "%d:1306 Link Up Event in loop back mode " |
887 | "x%x received Data: x%x x%x x%x x%x\n", | 915 | "x%x received Data: x%x x%x x%x x%x\n", |
@@ -896,14 +924,14 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
896 | la->granted_AL_PA, la->UlnkSpeed, | 924 | la->granted_AL_PA, la->UlnkSpeed, |
897 | phba->alpa_map[0]); | 925 | phba->alpa_map[0]); |
898 | } | 926 | } |
899 | lpfc_mbx_process_link_up(phba, la); | 927 | lpfc_mbx_process_link_up(vport, la); |
900 | } else { | 928 | } else { |
901 | phba->fc_stat.LinkDown++; | 929 | phba->fc_stat.LinkDown++; |
902 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | 930 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, |
903 | "%d:1305 Link Down Event x%x received " | 931 | "%d:1305 Link Down Event x%x received " |
904 | "Data: x%x x%x x%x\n", | 932 | "Data: x%x x%x x%x\n", |
905 | phba->brd_no, la->eventTag, phba->fc_eventTag, | 933 | phba->brd_no, la->eventTag, phba->fc_eventTag, |
906 | phba->hba_state, phba->fc_flag); | 934 | phba->pport->port_state, vport->fc_flag); |
907 | lpfc_mbx_issue_link_down(phba); | 935 | lpfc_mbx_issue_link_down(phba); |
908 | } | 936 | } |
909 | 937 | ||
@@ -921,26 +949,20 @@ lpfc_mbx_cmpl_read_la_free_mbuf: | |||
921 | * handed off to the SLI layer. | 949 | * handed off to the SLI layer. |
922 | */ | 950 | */ |
923 | void | 951 | void |
924 | lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 952 | lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
925 | { | 953 | { |
926 | struct lpfc_sli *psli; | 954 | struct lpfc_vport *vport = pmb->vport; |
927 | MAILBOX_t *mb; | 955 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; |
928 | struct lpfc_dmabuf *mp; | 956 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
929 | struct lpfc_nodelist *ndlp; | ||
930 | |||
931 | psli = &phba->sli; | ||
932 | mb = &pmb->mb; | ||
933 | 957 | ||
934 | ndlp = (struct lpfc_nodelist *) pmb->context2; | ||
935 | mp = (struct lpfc_dmabuf *) (pmb->context1); | ||
936 | 958 | ||
937 | pmb->context1 = NULL; | 959 | pmb->context1 = NULL; |
938 | 960 | ||
939 | /* Good status, call state machine */ | 961 | /* Good status, call state machine */ |
940 | lpfc_disc_state_machine(phba, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN); | 962 | lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN); |
941 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 963 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
942 | kfree(mp); | 964 | kfree(mp); |
943 | mempool_free( pmb, phba->mbox_mem_pool); | 965 | mempool_free(pmb, phba->mbox_mem_pool); |
944 | lpfc_nlp_put(ndlp); | 966 | lpfc_nlp_put(ndlp); |
945 | 967 | ||
946 | return; | 968 | return; |
@@ -953,20 +975,13 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
953 | * handed off to the SLI layer. | 975 | * handed off to the SLI layer. |
954 | */ | 976 | */ |
955 | void | 977 | void |
956 | lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 978 | lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
957 | { | 979 | { |
958 | struct lpfc_sli *psli; | 980 | struct lpfc_vport *vport = pmb->vport; |
959 | MAILBOX_t *mb; | 981 | MAILBOX_t *mb = &pmb->mb; |
960 | struct lpfc_dmabuf *mp; | 982 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
961 | struct lpfc_nodelist *ndlp; | 983 | struct lpfc_nodelist *ndlp, *ndlp_fdmi; |
962 | struct lpfc_nodelist *ndlp_fdmi; | ||
963 | |||
964 | |||
965 | psli = &phba->sli; | ||
966 | mb = &pmb->mb; | ||
967 | |||
968 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 984 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
969 | mp = (struct lpfc_dmabuf *) (pmb->context1); | ||
970 | 985 | ||
971 | pmb->context1 = NULL; | 986 | pmb->context1 = NULL; |
972 | pmb->context2 = NULL; | 987 | pmb->context2 = NULL; |
@@ -978,57 +993,59 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
978 | lpfc_nlp_put(ndlp); | 993 | lpfc_nlp_put(ndlp); |
979 | 994 | ||
980 | /* FLOGI failed, so just use loop map to make discovery list */ | 995 | /* FLOGI failed, so just use loop map to make discovery list */ |
981 | lpfc_disc_list_loopmap(phba); | 996 | lpfc_disc_list_loopmap(vport); |
982 | 997 | ||
983 | /* Start discovery */ | 998 | /* Start discovery */ |
984 | lpfc_disc_start(phba); | 999 | lpfc_disc_start(vport); |
985 | return; | 1000 | return; |
986 | } | 1001 | } |
987 | 1002 | ||
988 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1003 | ndlp->nlp_rpi = mb->un.varWords[0]; |
989 | ndlp->nlp_type |= NLP_FABRIC; | 1004 | ndlp->nlp_type |= NLP_FABRIC; |
990 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 1005 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
991 | 1006 | ||
992 | lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */ | 1007 | lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */ |
993 | 1008 | ||
994 | if (phba->hba_state == LPFC_FABRIC_CFG_LINK) { | 1009 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { |
995 | /* This NPort has been assigned an NPort_ID by the fabric as a | 1010 | /* This NPort has been assigned an NPort_ID by the fabric as a |
996 | * result of the completed fabric login. Issue a State Change | 1011 | * result of the completed fabric login. Issue a State Change |
997 | * Registration (SCR) ELS request to the fabric controller | 1012 | * Registration (SCR) ELS request to the fabric controller |
998 | * (SCR_DID) so that this NPort gets RSCN events from the | 1013 | * (SCR_DID) so that this NPort gets RSCN events from the |
999 | * fabric. | 1014 | * fabric. |
1000 | */ | 1015 | */ |
1001 | lpfc_issue_els_scr(phba, SCR_DID, 0); | 1016 | lpfc_issue_els_scr(vport, SCR_DID, 0); |
1002 | 1017 | ||
1003 | ndlp = lpfc_findnode_did(phba, NameServer_DID); | 1018 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
1004 | if (!ndlp) { | 1019 | if (!ndlp) { |
1005 | /* Allocate a new node instance. If the pool is empty, | 1020 | /* Allocate a new node instance. If the pool is empty, |
1006 | * start the discovery process and skip the Nameserver | 1021 | * start the discovery process and skip the Nameserver |
1007 | * login process. This is attempted again later on. | 1022 | * login process. This is attempted again later on. |
1008 | * Otherwise, issue a Port Login (PLOGI) to NameServer. | 1023 | * Otherwise, issue a Port Login (PLOGI) to |
1024 | * the NameServer | ||
1009 | */ | 1025 | */ |
1010 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); | 1026 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
1011 | if (!ndlp) { | 1027 | if (!ndlp) { |
1012 | lpfc_disc_start(phba); | 1028 | lpfc_disc_start(vport); |
1013 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1029 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1014 | kfree(mp); | 1030 | kfree(mp); |
1015 | mempool_free(pmb, phba->mbox_mem_pool); | 1031 | mempool_free(pmb, phba->mbox_mem_pool); |
1016 | return; | 1032 | return; |
1017 | } else { | 1033 | } else { |
1018 | lpfc_nlp_init(phba, ndlp, NameServer_DID); | 1034 | lpfc_nlp_init(vport, ndlp, NameServer_DID); |
1019 | ndlp->nlp_type |= NLP_FABRIC; | 1035 | ndlp->nlp_type |= NLP_FABRIC; |
1020 | } | 1036 | } |
1021 | } | 1037 | } |
1022 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 1038 | |
1023 | lpfc_issue_els_plogi(phba, NameServer_DID, 0); | 1039 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
1040 | lpfc_issue_els_plogi(vport, NameServer_DID, 0); | ||
1024 | if (phba->cfg_fdmi_on) { | 1041 | if (phba->cfg_fdmi_on) { |
1025 | ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, | 1042 | ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, |
1026 | GFP_KERNEL); | 1043 | GFP_KERNEL); |
1027 | if (ndlp_fdmi) { | 1044 | if (ndlp_fdmi) { |
1028 | lpfc_nlp_init(phba, ndlp_fdmi, FDMI_DID); | 1045 | lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); |
1029 | ndlp_fdmi->nlp_type |= NLP_FABRIC; | 1046 | ndlp_fdmi->nlp_type |= NLP_FABRIC; |
1030 | ndlp_fdmi->nlp_state = NLP_STE_PLOGI_ISSUE; | 1047 | ndlp_fdmi->nlp_state = NLP_STE_PLOGI_ISSUE; |
1031 | lpfc_issue_els_plogi(phba, FDMI_DID, 0); | 1048 | lpfc_issue_els_plogi(vport, FDMI_DID, 0); |
1032 | } | 1049 | } |
1033 | } | 1050 | } |
1034 | } | 1051 | } |
@@ -1046,32 +1063,28 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
1046 | * handed off to the SLI layer. | 1063 | * handed off to the SLI layer. |
1047 | */ | 1064 | */ |
1048 | void | 1065 | void |
1049 | lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 1066 | lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
1050 | { | 1067 | { |
1051 | struct lpfc_sli *psli; | 1068 | MAILBOX_t *mb = &pmb->mb; |
1052 | MAILBOX_t *mb; | 1069 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
1053 | struct lpfc_dmabuf *mp; | 1070 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
1054 | struct lpfc_nodelist *ndlp; | 1071 | struct lpfc_vport *vport = pmb->vport; |
1055 | |||
1056 | psli = &phba->sli; | ||
1057 | mb = &pmb->mb; | ||
1058 | |||
1059 | ndlp = (struct lpfc_nodelist *) pmb->context2; | ||
1060 | mp = (struct lpfc_dmabuf *) (pmb->context1); | ||
1061 | 1072 | ||
1062 | if (mb->mbxStatus) { | 1073 | if (mb->mbxStatus) { |
1063 | lpfc_nlp_put(ndlp); | 1074 | lpfc_nlp_put(ndlp); |
1064 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1075 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1065 | kfree(mp); | 1076 | kfree(mp); |
1066 | mempool_free(pmb, phba->mbox_mem_pool); | 1077 | mempool_free(pmb, phba->mbox_mem_pool); |
1067 | lpfc_drop_node(phba, ndlp); | 1078 | lpfc_drop_node(vport, ndlp); |
1068 | 1079 | ||
1069 | /* RegLogin failed, so just use loop map to make discovery | 1080 | /* |
1070 | list */ | 1081 | * RegLogin failed, so just use loop map to make discovery |
1071 | lpfc_disc_list_loopmap(phba); | 1082 | * list |
1083 | */ | ||
1084 | lpfc_disc_list_loopmap(vport); | ||
1072 | 1085 | ||
1073 | /* Start discovery */ | 1086 | /* Start discovery */ |
1074 | lpfc_disc_start(phba); | 1087 | lpfc_disc_start(vport); |
1075 | return; | 1088 | return; |
1076 | } | 1089 | } |
1077 | 1090 | ||
@@ -1079,37 +1092,39 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
1079 | 1092 | ||
1080 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1093 | ndlp->nlp_rpi = mb->un.varWords[0]; |
1081 | ndlp->nlp_type |= NLP_FABRIC; | 1094 | ndlp->nlp_type |= NLP_FABRIC; |
1082 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 1095 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1083 | 1096 | ||
1084 | if (phba->hba_state < LPFC_HBA_READY) { | 1097 | if (vport->port_state < LPFC_VPORT_READY) { |
1085 | /* Link up discovery requires Fabrib registration. */ | 1098 | /* Link up discovery requires Fabric registration. */ |
1086 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RNN_ID); | 1099 | lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RNN_ID); |
1087 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RSNN_NN); | 1100 | lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RSNN_NN); |
1088 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFT_ID); | 1101 | lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RFT_ID); |
1089 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFF_ID); | 1102 | lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RFF_ID); |
1090 | } | 1103 | } |
1091 | 1104 | ||
1092 | phba->fc_ns_retry = 0; | 1105 | vport->fc_ns_retry = 0; |
1093 | /* Good status, issue CT Request to NameServer */ | 1106 | /* Good status, issue CT Request to NameServer */ |
1094 | if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT)) { | 1107 | if (lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT)) { |
1095 | /* Cannot issue NameServer Query, so finish up discovery */ | 1108 | /* Cannot issue NameServer Query, so finish up discovery */ |
1096 | lpfc_disc_start(phba); | 1109 | lpfc_disc_start(vport); |
1097 | } | 1110 | } |
1098 | 1111 | ||
1099 | lpfc_nlp_put(ndlp); | 1112 | lpfc_nlp_put(ndlp); |
1100 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1113 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1101 | kfree(mp); | 1114 | kfree(mp); |
1102 | mempool_free( pmb, phba->mbox_mem_pool); | 1115 | mempool_free(pmb, phba->mbox_mem_pool); |
1103 | 1116 | ||
1104 | return; | 1117 | return; |
1105 | } | 1118 | } |
1106 | 1119 | ||
1107 | static void | 1120 | static void |
1108 | lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 1121 | lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1109 | { | 1122 | { |
1110 | struct fc_rport *rport; | 1123 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1124 | struct fc_rport *rport; | ||
1111 | struct lpfc_rport_data *rdata; | 1125 | struct lpfc_rport_data *rdata; |
1112 | struct fc_rport_identifiers rport_ids; | 1126 | struct fc_rport_identifiers rport_ids; |
1127 | struct lpfc_hba *phba = vport->phba; | ||
1113 | 1128 | ||
1114 | /* Remote port has reappeared. Re-register w/ FC transport */ | 1129 | /* Remote port has reappeared. Re-register w/ FC transport */ |
1115 | rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn); | 1130 | rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn); |
@@ -1128,7 +1143,7 @@ lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
1128 | *(struct lpfc_rport_data **) ndlp->rport->dd_data) { | 1143 | *(struct lpfc_rport_data **) ndlp->rport->dd_data) { |
1129 | lpfc_nlp_put(ndlp); | 1144 | lpfc_nlp_put(ndlp); |
1130 | } | 1145 | } |
1131 | ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids); | 1146 | ndlp->rport = rport = fc_remote_port_add(shost, 0, &rport_ids); |
1132 | if (!rport || !get_device(&rport->dev)) { | 1147 | if (!rport || !get_device(&rport->dev)) { |
1133 | dev_printk(KERN_WARNING, &phba->pcidev->dev, | 1148 | dev_printk(KERN_WARNING, &phba->pcidev->dev, |
1134 | "Warning: fc_remote_port_add failed\n"); | 1149 | "Warning: fc_remote_port_add failed\n"); |
@@ -1159,7 +1174,7 @@ lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
1159 | } | 1174 | } |
1160 | 1175 | ||
1161 | static void | 1176 | static void |
1162 | lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 1177 | lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp) |
1163 | { | 1178 | { |
1164 | struct fc_rport *rport = ndlp->rport; | 1179 | struct fc_rport *rport = ndlp->rport; |
1165 | struct lpfc_rport_data *rdata = rport->dd_data; | 1180 | struct lpfc_rport_data *rdata = rport->dd_data; |
@@ -1177,42 +1192,46 @@ lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
1177 | } | 1192 | } |
1178 | 1193 | ||
1179 | static void | 1194 | static void |
1180 | lpfc_nlp_counters(struct lpfc_hba *phba, int state, int count) | 1195 | lpfc_nlp_counters(struct lpfc_vport *vport, int state, int count) |
1181 | { | 1196 | { |
1182 | spin_lock_irq(phba->host->host_lock); | 1197 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1198 | |||
1199 | spin_lock_irq(shost->host_lock); | ||
1183 | switch (state) { | 1200 | switch (state) { |
1184 | case NLP_STE_UNUSED_NODE: | 1201 | case NLP_STE_UNUSED_NODE: |
1185 | phba->fc_unused_cnt += count; | 1202 | vport->fc_unused_cnt += count; |
1186 | break; | 1203 | break; |
1187 | case NLP_STE_PLOGI_ISSUE: | 1204 | case NLP_STE_PLOGI_ISSUE: |
1188 | phba->fc_plogi_cnt += count; | 1205 | vport->fc_plogi_cnt += count; |
1189 | break; | 1206 | break; |
1190 | case NLP_STE_ADISC_ISSUE: | 1207 | case NLP_STE_ADISC_ISSUE: |
1191 | phba->fc_adisc_cnt += count; | 1208 | vport->fc_adisc_cnt += count; |
1192 | break; | 1209 | break; |
1193 | case NLP_STE_REG_LOGIN_ISSUE: | 1210 | case NLP_STE_REG_LOGIN_ISSUE: |
1194 | phba->fc_reglogin_cnt += count; | 1211 | vport->fc_reglogin_cnt += count; |
1195 | break; | 1212 | break; |
1196 | case NLP_STE_PRLI_ISSUE: | 1213 | case NLP_STE_PRLI_ISSUE: |
1197 | phba->fc_prli_cnt += count; | 1214 | vport->fc_prli_cnt += count; |
1198 | break; | 1215 | break; |
1199 | case NLP_STE_UNMAPPED_NODE: | 1216 | case NLP_STE_UNMAPPED_NODE: |
1200 | phba->fc_unmap_cnt += count; | 1217 | vport->fc_unmap_cnt += count; |
1201 | break; | 1218 | break; |
1202 | case NLP_STE_MAPPED_NODE: | 1219 | case NLP_STE_MAPPED_NODE: |
1203 | phba->fc_map_cnt += count; | 1220 | vport->fc_map_cnt += count; |
1204 | break; | 1221 | break; |
1205 | case NLP_STE_NPR_NODE: | 1222 | case NLP_STE_NPR_NODE: |
1206 | phba->fc_npr_cnt += count; | 1223 | vport->fc_npr_cnt += count; |
1207 | break; | 1224 | break; |
1208 | } | 1225 | } |
1209 | spin_unlock_irq(phba->host->host_lock); | 1226 | spin_unlock_irq(shost->host_lock); |
1210 | } | 1227 | } |
1211 | 1228 | ||
1212 | static void | 1229 | static void |
1213 | lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | 1230 | lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1214 | int old_state, int new_state) | 1231 | int old_state, int new_state) |
1215 | { | 1232 | { |
1233 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1234 | |||
1216 | if (new_state == NLP_STE_UNMAPPED_NODE) { | 1235 | if (new_state == NLP_STE_UNMAPPED_NODE) { |
1217 | ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); | 1236 | ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); |
1218 | ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; | 1237 | ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; |
@@ -1226,19 +1245,19 @@ lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
1226 | /* Transport interface */ | 1245 | /* Transport interface */ |
1227 | if (ndlp->rport && (old_state == NLP_STE_MAPPED_NODE || | 1246 | if (ndlp->rport && (old_state == NLP_STE_MAPPED_NODE || |
1228 | old_state == NLP_STE_UNMAPPED_NODE)) { | 1247 | old_state == NLP_STE_UNMAPPED_NODE)) { |
1229 | phba->nport_event_cnt++; | 1248 | vport->phba->nport_event_cnt++; |
1230 | lpfc_unregister_remote_port(phba, ndlp); | 1249 | lpfc_unregister_remote_port(ndlp); |
1231 | } | 1250 | } |
1232 | 1251 | ||
1233 | if (new_state == NLP_STE_MAPPED_NODE || | 1252 | if (new_state == NLP_STE_MAPPED_NODE || |
1234 | new_state == NLP_STE_UNMAPPED_NODE) { | 1253 | new_state == NLP_STE_UNMAPPED_NODE) { |
1235 | phba->nport_event_cnt++; | 1254 | vport->phba->nport_event_cnt++; |
1236 | /* | 1255 | /* |
1237 | * Tell the fc transport about the port, if we haven't | 1256 | * Tell the fc transport about the port, if we haven't |
1238 | * already. If we have, and it's a scsi entity, be | 1257 | * already. If we have, and it's a scsi entity, be |
1239 | * sure to unblock any attached scsi devices | 1258 | * sure to unblock any attached scsi devices |
1240 | */ | 1259 | */ |
1241 | lpfc_register_remote_port(phba, ndlp); | 1260 | lpfc_register_remote_port(vport, ndlp); |
1242 | } | 1261 | } |
1243 | 1262 | ||
1244 | /* | 1263 | /* |
@@ -1251,10 +1270,10 @@ lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
1251 | (!ndlp->rport || | 1270 | (!ndlp->rport || |
1252 | ndlp->rport->scsi_target_id == -1 || | 1271 | ndlp->rport->scsi_target_id == -1 || |
1253 | ndlp->rport->scsi_target_id >= LPFC_MAX_TARGET)) { | 1272 | ndlp->rport->scsi_target_id >= LPFC_MAX_TARGET)) { |
1254 | spin_lock_irq(phba->host->host_lock); | 1273 | spin_lock_irq(shost->host_lock); |
1255 | ndlp->nlp_flag |= NLP_TGT_NO_SCSIID; | 1274 | ndlp->nlp_flag |= NLP_TGT_NO_SCSIID; |
1256 | spin_unlock_irq(phba->host->host_lock); | 1275 | spin_unlock_irq(shost->host_lock); |
1257 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 1276 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1258 | } | 1277 | } |
1259 | } | 1278 | } |
1260 | 1279 | ||
@@ -1280,61 +1299,67 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state) | |||
1280 | } | 1299 | } |
1281 | 1300 | ||
1282 | void | 1301 | void |
1283 | lpfc_nlp_set_state(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, int state) | 1302 | lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1303 | int state) | ||
1284 | { | 1304 | { |
1305 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1285 | int old_state = ndlp->nlp_state; | 1306 | int old_state = ndlp->nlp_state; |
1286 | char name1[16], name2[16]; | 1307 | char name1[16], name2[16]; |
1287 | 1308 | ||
1288 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | 1309 | lpfc_printf_log(vport->phba, KERN_INFO, LOG_NODE, |
1289 | "%d:0904 NPort state transition x%06x, %s -> %s\n", | 1310 | "%d:0904 NPort state transition x%06x, %s -> %s\n", |
1290 | phba->brd_no, | 1311 | vport->phba->brd_no, |
1291 | ndlp->nlp_DID, | 1312 | ndlp->nlp_DID, |
1292 | lpfc_nlp_state_name(name1, sizeof(name1), old_state), | 1313 | lpfc_nlp_state_name(name1, sizeof(name1), old_state), |
1293 | lpfc_nlp_state_name(name2, sizeof(name2), state)); | 1314 | lpfc_nlp_state_name(name2, sizeof(name2), state)); |
1294 | if (old_state == NLP_STE_NPR_NODE && | 1315 | if (old_state == NLP_STE_NPR_NODE && |
1295 | (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 && | 1316 | (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 && |
1296 | state != NLP_STE_NPR_NODE) | 1317 | state != NLP_STE_NPR_NODE) |
1297 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1318 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1298 | if (old_state == NLP_STE_UNMAPPED_NODE) { | 1319 | if (old_state == NLP_STE_UNMAPPED_NODE) { |
1299 | ndlp->nlp_flag &= ~NLP_TGT_NO_SCSIID; | 1320 | ndlp->nlp_flag &= ~NLP_TGT_NO_SCSIID; |
1300 | ndlp->nlp_type &= ~NLP_FC_NODE; | 1321 | ndlp->nlp_type &= ~NLP_FC_NODE; |
1301 | } | 1322 | } |
1302 | 1323 | ||
1303 | if (list_empty(&ndlp->nlp_listp)) { | 1324 | if (list_empty(&ndlp->nlp_listp)) { |
1304 | spin_lock_irq(phba->host->host_lock); | 1325 | spin_lock_irq(shost->host_lock); |
1305 | list_add_tail(&ndlp->nlp_listp, &phba->fc_nodes); | 1326 | list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes); |
1306 | spin_unlock_irq(phba->host->host_lock); | 1327 | spin_unlock_irq(shost->host_lock); |
1307 | } else if (old_state) | 1328 | } else if (old_state) |
1308 | lpfc_nlp_counters(phba, old_state, -1); | 1329 | lpfc_nlp_counters(vport, old_state, -1); |
1309 | 1330 | ||
1310 | ndlp->nlp_state = state; | 1331 | ndlp->nlp_state = state; |
1311 | lpfc_nlp_counters(phba, state, 1); | 1332 | lpfc_nlp_counters(vport, state, 1); |
1312 | lpfc_nlp_state_cleanup(phba, ndlp, old_state, state); | 1333 | lpfc_nlp_state_cleanup(vport, ndlp, old_state, state); |
1313 | } | 1334 | } |
1314 | 1335 | ||
1315 | void | 1336 | void |
1316 | lpfc_dequeue_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 1337 | lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1317 | { | 1338 | { |
1339 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1340 | |||
1318 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) | 1341 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) |
1319 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1342 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1320 | if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) | 1343 | if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) |
1321 | lpfc_nlp_counters(phba, ndlp->nlp_state, -1); | 1344 | lpfc_nlp_counters(vport, ndlp->nlp_state, -1); |
1322 | spin_lock_irq(phba->host->host_lock); | 1345 | spin_lock_irq(shost->host_lock); |
1323 | list_del_init(&ndlp->nlp_listp); | 1346 | list_del_init(&ndlp->nlp_listp); |
1324 | spin_unlock_irq(phba->host->host_lock); | 1347 | spin_unlock_irq(shost->host_lock); |
1325 | lpfc_nlp_state_cleanup(phba, ndlp, ndlp->nlp_state, 0); | 1348 | lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state, 0); |
1326 | } | 1349 | } |
1327 | 1350 | ||
1328 | void | 1351 | void |
1329 | lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 1352 | lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1330 | { | 1353 | { |
1354 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1355 | |||
1331 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) | 1356 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) |
1332 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1357 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1333 | if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) | 1358 | if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) |
1334 | lpfc_nlp_counters(phba, ndlp->nlp_state, -1); | 1359 | lpfc_nlp_counters(vport, ndlp->nlp_state, -1); |
1335 | spin_lock_irq(phba->host->host_lock); | 1360 | spin_lock_irq(shost->host_lock); |
1336 | list_del_init(&ndlp->nlp_listp); | 1361 | list_del_init(&ndlp->nlp_listp); |
1337 | spin_unlock_irq(phba->host->host_lock); | 1362 | spin_unlock_irq(shost->host_lock); |
1338 | lpfc_nlp_put(ndlp); | 1363 | lpfc_nlp_put(ndlp); |
1339 | } | 1364 | } |
1340 | 1365 | ||
@@ -1342,11 +1367,13 @@ lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
1342 | * Start / ReStart rescue timer for Discovery / RSCN handling | 1367 | * Start / ReStart rescue timer for Discovery / RSCN handling |
1343 | */ | 1368 | */ |
1344 | void | 1369 | void |
1345 | lpfc_set_disctmo(struct lpfc_hba * phba) | 1370 | lpfc_set_disctmo(struct lpfc_vport *vport) |
1346 | { | 1371 | { |
1372 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1373 | struct lpfc_hba *phba = vport->phba; | ||
1347 | uint32_t tmo; | 1374 | uint32_t tmo; |
1348 | 1375 | ||
1349 | if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { | 1376 | if (vport->port_state == LPFC_LOCAL_CFG_LINK) { |
1350 | /* For FAN, timeout should be greater then edtov */ | 1377 | /* For FAN, timeout should be greater then edtov */ |
1351 | tmo = (((phba->fc_edtov + 999) / 1000) + 1); | 1378 | tmo = (((phba->fc_edtov + 999) / 1000) + 1); |
1352 | } else { | 1379 | } else { |
@@ -1356,18 +1383,18 @@ lpfc_set_disctmo(struct lpfc_hba * phba) | |||
1356 | tmo = ((phba->fc_ratov * 3) + 3); | 1383 | tmo = ((phba->fc_ratov * 3) + 3); |
1357 | } | 1384 | } |
1358 | 1385 | ||
1359 | mod_timer(&phba->fc_disctmo, jiffies + HZ * tmo); | 1386 | mod_timer(&vport->fc_disctmo, jiffies + HZ * tmo); |
1360 | spin_lock_irq(phba->host->host_lock); | 1387 | spin_lock_irq(shost->host_lock); |
1361 | phba->fc_flag |= FC_DISC_TMO; | 1388 | vport->fc_flag |= FC_DISC_TMO; |
1362 | spin_unlock_irq(phba->host->host_lock); | 1389 | spin_unlock_irq(shost->host_lock); |
1363 | 1390 | ||
1364 | /* Start Discovery Timer state <hba_state> */ | 1391 | /* Start Discovery Timer state <hba_state> */ |
1365 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 1392 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
1366 | "%d:0247 Start Discovery Timer state x%x " | 1393 | "%d:0247 Start Discovery Timer state x%x " |
1367 | "Data: x%x x%lx x%x x%x\n", | 1394 | "Data: x%x x%lx x%x x%x\n", |
1368 | phba->brd_no, | 1395 | phba->brd_no, vport->port_state, tmo, |
1369 | phba->hba_state, tmo, (unsigned long)&phba->fc_disctmo, | 1396 | (unsigned long)&vport->fc_disctmo, vport->fc_plogi_cnt, |
1370 | phba->fc_plogi_cnt, phba->fc_adisc_cnt); | 1397 | vport->fc_adisc_cnt); |
1371 | 1398 | ||
1372 | return; | 1399 | return; |
1373 | } | 1400 | } |
@@ -1376,23 +1403,29 @@ lpfc_set_disctmo(struct lpfc_hba * phba) | |||
1376 | * Cancel rescue timer for Discovery / RSCN handling | 1403 | * Cancel rescue timer for Discovery / RSCN handling |
1377 | */ | 1404 | */ |
1378 | int | 1405 | int |
1379 | lpfc_can_disctmo(struct lpfc_hba * phba) | 1406 | lpfc_can_disctmo(struct lpfc_vport *vport) |
1380 | { | 1407 | { |
1408 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1409 | struct lpfc_hba *phba = vport->phba; | ||
1410 | unsigned long iflags; | ||
1411 | |||
1381 | /* Turn off discovery timer if its running */ | 1412 | /* Turn off discovery timer if its running */ |
1382 | if (phba->fc_flag & FC_DISC_TMO) { | 1413 | if (vport->fc_flag & FC_DISC_TMO) { |
1383 | spin_lock_irq(phba->host->host_lock); | 1414 | spin_lock_irqsave(shost->host_lock, iflags); |
1384 | phba->fc_flag &= ~FC_DISC_TMO; | 1415 | vport->fc_flag &= ~FC_DISC_TMO; |
1385 | spin_unlock_irq(phba->host->host_lock); | 1416 | spin_unlock_irqrestore(shost->host_lock, iflags); |
1386 | del_timer_sync(&phba->fc_disctmo); | 1417 | del_timer_sync(&vport->fc_disctmo); |
1387 | phba->work_hba_events &= ~WORKER_DISC_TMO; | 1418 | spin_lock_irqsave(&vport->work_port_lock, iflags); |
1419 | vport->work_port_events &= ~WORKER_DISC_TMO; | ||
1420 | spin_unlock_irqrestore(&vport->work_port_lock, iflags); | ||
1388 | } | 1421 | } |
1389 | 1422 | ||
1390 | /* Cancel Discovery Timer state <hba_state> */ | 1423 | /* Cancel Discovery Timer state <hba_state> */ |
1391 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 1424 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
1392 | "%d:0248 Cancel Discovery Timer state x%x " | 1425 | "%d:0248 Cancel Discovery Timer state x%x " |
1393 | "Data: x%x x%x x%x\n", | 1426 | "Data: x%x x%x x%x\n", |
1394 | phba->brd_no, phba->hba_state, phba->fc_flag, | 1427 | phba->brd_no, vport->port_state, vport->fc_flag, |
1395 | phba->fc_plogi_cnt, phba->fc_adisc_cnt); | 1428 | vport->fc_plogi_cnt, vport->fc_adisc_cnt); |
1396 | 1429 | ||
1397 | return 0; | 1430 | return 0; |
1398 | } | 1431 | } |
@@ -1402,15 +1435,13 @@ lpfc_can_disctmo(struct lpfc_hba * phba) | |||
1402 | * Return true if iocb matches the specified nport | 1435 | * Return true if iocb matches the specified nport |
1403 | */ | 1436 | */ |
1404 | int | 1437 | int |
1405 | lpfc_check_sli_ndlp(struct lpfc_hba * phba, | 1438 | lpfc_check_sli_ndlp(struct lpfc_hba *phba, |
1406 | struct lpfc_sli_ring * pring, | 1439 | struct lpfc_sli_ring *pring, |
1407 | struct lpfc_iocbq * iocb, struct lpfc_nodelist * ndlp) | 1440 | struct lpfc_iocbq *iocb, |
1441 | struct lpfc_nodelist *ndlp) | ||
1408 | { | 1442 | { |
1409 | struct lpfc_sli *psli; | 1443 | struct lpfc_sli *psli = &phba->sli; |
1410 | IOCB_t *icmd; | 1444 | IOCB_t *icmd = &iocb->iocb; |
1411 | |||
1412 | psli = &phba->sli; | ||
1413 | icmd = &iocb->iocb; | ||
1414 | if (pring->ringno == LPFC_ELS_RING) { | 1445 | if (pring->ringno == LPFC_ELS_RING) { |
1415 | switch (icmd->ulpCommand) { | 1446 | switch (icmd->ulpCommand) { |
1416 | case CMD_GEN_REQUEST64_CR: | 1447 | case CMD_GEN_REQUEST64_CR: |
@@ -1445,7 +1476,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, | |||
1445 | * associated with nlp_rpi in the LPFC_NODELIST entry. | 1476 | * associated with nlp_rpi in the LPFC_NODELIST entry. |
1446 | */ | 1477 | */ |
1447 | static int | 1478 | static int |
1448 | lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1479 | lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) |
1449 | { | 1480 | { |
1450 | LIST_HEAD(completions); | 1481 | LIST_HEAD(completions); |
1451 | struct lpfc_sli *psli; | 1482 | struct lpfc_sli *psli; |
@@ -1465,9 +1496,9 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1465 | for (i = 0; i < psli->num_rings; i++) { | 1496 | for (i = 0; i < psli->num_rings; i++) { |
1466 | pring = &psli->ring[i]; | 1497 | pring = &psli->ring[i]; |
1467 | 1498 | ||
1468 | spin_lock_irq(phba->host->host_lock); | 1499 | spin_lock_irq(&phba->hbalock); |
1469 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, | 1500 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, |
1470 | list) { | 1501 | list) { |
1471 | /* | 1502 | /* |
1472 | * Check to see if iocb matches the nport we are | 1503 | * Check to see if iocb matches the nport we are |
1473 | * looking for | 1504 | * looking for |
@@ -1481,8 +1512,7 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1481 | pring->txq_cnt--; | 1512 | pring->txq_cnt--; |
1482 | } | 1513 | } |
1483 | } | 1514 | } |
1484 | spin_unlock_irq(phba->host->host_lock); | 1515 | spin_unlock_irq(&phba->hbalock); |
1485 | |||
1486 | } | 1516 | } |
1487 | } | 1517 | } |
1488 | 1518 | ||
@@ -1490,13 +1520,14 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1490 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | 1520 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); |
1491 | list_del(&iocb->list); | 1521 | list_del(&iocb->list); |
1492 | 1522 | ||
1493 | if (iocb->iocb_cmpl) { | 1523 | if (!iocb->iocb_cmpl) |
1524 | lpfc_sli_release_iocbq(phba, iocb); | ||
1525 | else { | ||
1494 | icmd = &iocb->iocb; | 1526 | icmd = &iocb->iocb; |
1495 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 1527 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
1496 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | 1528 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
1497 | (iocb->iocb_cmpl) (phba, iocb, iocb); | 1529 | (iocb->iocb_cmpl)(phba, iocb, iocb); |
1498 | } else | 1530 | } |
1499 | lpfc_sli_release_iocbq(phba, iocb); | ||
1500 | } | 1531 | } |
1501 | 1532 | ||
1502 | return 0; | 1533 | return 0; |
@@ -1512,19 +1543,21 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1512 | * we are waiting to PLOGI back to the remote NPort. | 1543 | * we are waiting to PLOGI back to the remote NPort. |
1513 | */ | 1544 | */ |
1514 | int | 1545 | int |
1515 | lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1546 | lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1516 | { | 1547 | { |
1517 | LPFC_MBOXQ_t *mbox; | 1548 | struct lpfc_hba *phba = vport->phba; |
1549 | LPFC_MBOXQ_t *mbox; | ||
1518 | int rc; | 1550 | int rc; |
1519 | 1551 | ||
1520 | if (ndlp->nlp_rpi) { | 1552 | if (ndlp->nlp_rpi) { |
1521 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { | 1553 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
1554 | if (mbox) { | ||
1522 | lpfc_unreg_login(phba, ndlp->nlp_rpi, mbox); | 1555 | lpfc_unreg_login(phba, ndlp->nlp_rpi, mbox); |
1523 | mbox->mbox_cmpl=lpfc_sli_def_mbox_cmpl; | 1556 | mbox->mbox_cmpl=lpfc_sli_def_mbox_cmpl; |
1524 | rc = lpfc_sli_issue_mbox | 1557 | rc = lpfc_sli_issue_mbox |
1525 | (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); | 1558 | (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); |
1526 | if (rc == MBX_NOT_FINISHED) | 1559 | if (rc == MBX_NOT_FINISHED) |
1527 | mempool_free( mbox, phba->mbox_mem_pool); | 1560 | mempool_free(mbox, phba->mbox_mem_pool); |
1528 | } | 1561 | } |
1529 | lpfc_no_rpi(phba, ndlp); | 1562 | lpfc_no_rpi(phba, ndlp); |
1530 | ndlp->nlp_rpi = 0; | 1563 | ndlp->nlp_rpi = 0; |
@@ -1538,10 +1571,11 @@ lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1538 | * so it can be freed. | 1571 | * so it can be freed. |
1539 | */ | 1572 | */ |
1540 | static int | 1573 | static int |
1541 | lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1574 | lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1542 | { | 1575 | { |
1543 | LPFC_MBOXQ_t *mb; | 1576 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1544 | LPFC_MBOXQ_t *nextmb; | 1577 | struct lpfc_hba *phba = vport->phba; |
1578 | LPFC_MBOXQ_t *mb, *nextmb; | ||
1545 | struct lpfc_dmabuf *mp; | 1579 | struct lpfc_dmabuf *mp; |
1546 | 1580 | ||
1547 | /* Cleanup node for NPort <nlp_DID> */ | 1581 | /* Cleanup node for NPort <nlp_DID> */ |
@@ -1551,7 +1585,7 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1551 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, | 1585 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, |
1552 | ndlp->nlp_state, ndlp->nlp_rpi); | 1586 | ndlp->nlp_state, ndlp->nlp_rpi); |
1553 | 1587 | ||
1554 | lpfc_dequeue_node(phba, ndlp); | 1588 | lpfc_dequeue_node(vport, ndlp); |
1555 | 1589 | ||
1556 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ | 1590 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ |
1557 | if ((mb = phba->sli.mbox_active)) { | 1591 | if ((mb = phba->sli.mbox_active)) { |
@@ -1562,13 +1596,13 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1562 | } | 1596 | } |
1563 | } | 1597 | } |
1564 | 1598 | ||
1565 | spin_lock_irq(phba->host->host_lock); | 1599 | spin_lock_irq(&phba->hbalock); |
1566 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { | 1600 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { |
1567 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 1601 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && |
1568 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 1602 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
1569 | mp = (struct lpfc_dmabuf *) (mb->context1); | 1603 | mp = (struct lpfc_dmabuf *) (mb->context1); |
1570 | if (mp) { | 1604 | if (mp) { |
1571 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1605 | __lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1572 | kfree(mp); | 1606 | kfree(mp); |
1573 | } | 1607 | } |
1574 | list_del(&mb->list); | 1608 | list_del(&mb->list); |
@@ -1576,12 +1610,12 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1576 | lpfc_nlp_put(ndlp); | 1610 | lpfc_nlp_put(ndlp); |
1577 | } | 1611 | } |
1578 | } | 1612 | } |
1579 | spin_unlock_irq(phba->host->host_lock); | 1613 | spin_unlock_irq(&phba->hbalock); |
1580 | 1614 | ||
1581 | lpfc_els_abort(phba,ndlp); | 1615 | lpfc_els_abort(phba,ndlp); |
1582 | spin_lock_irq(phba->host->host_lock); | 1616 | spin_lock_irq(shost->host_lock); |
1583 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 1617 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; |
1584 | spin_unlock_irq(phba->host->host_lock); | 1618 | spin_unlock_irq(shost->host_lock); |
1585 | 1619 | ||
1586 | ndlp->nlp_last_elscmd = 0; | 1620 | ndlp->nlp_last_elscmd = 0; |
1587 | del_timer_sync(&ndlp->nlp_delayfunc); | 1621 | del_timer_sync(&ndlp->nlp_delayfunc); |
@@ -1589,7 +1623,7 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1589 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | 1623 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) |
1590 | list_del_init(&ndlp->els_retry_evt.evt_listp); | 1624 | list_del_init(&ndlp->els_retry_evt.evt_listp); |
1591 | 1625 | ||
1592 | lpfc_unreg_rpi(phba, ndlp); | 1626 | lpfc_unreg_rpi(vport, ndlp); |
1593 | 1627 | ||
1594 | return 0; | 1628 | return 0; |
1595 | } | 1629 | } |
@@ -1600,17 +1634,22 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1600 | * machine, defer the free till we reach the end of the state machine. | 1634 | * machine, defer the free till we reach the end of the state machine. |
1601 | */ | 1635 | */ |
1602 | static void | 1636 | static void |
1603 | lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 1637 | lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1604 | { | 1638 | { |
1605 | struct lpfc_rport_data *rdata; | 1639 | struct lpfc_rport_data *rdata; |
1606 | 1640 | ||
1607 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 1641 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
1608 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1642 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1609 | } | 1643 | } |
1610 | 1644 | ||
1611 | lpfc_cleanup_node(phba, ndlp); | 1645 | lpfc_cleanup_node(vport, ndlp); |
1612 | 1646 | ||
1613 | if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { | 1647 | /* |
1648 | * We should never get here with a non-NULL ndlp->rport. But | ||
1649 | * if we do, drop the reference to the rport. That seems the | ||
1650 | * intelligent thing to do. | ||
1651 | */ | ||
1652 | if (ndlp->rport && !(vport->load_flag & FC_UNLOADING)) { | ||
1614 | put_device(&ndlp->rport->dev); | 1653 | put_device(&ndlp->rport->dev); |
1615 | rdata = ndlp->rport->dd_data; | 1654 | rdata = ndlp->rport->dd_data; |
1616 | rdata->pnode = NULL; | 1655 | rdata->pnode = NULL; |
@@ -1619,11 +1658,10 @@ lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
1619 | } | 1658 | } |
1620 | 1659 | ||
1621 | static int | 1660 | static int |
1622 | lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) | 1661 | lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1662 | uint32_t did) | ||
1623 | { | 1663 | { |
1624 | D_ID mydid; | 1664 | D_ID mydid, ndlpdid, matchdid; |
1625 | D_ID ndlpdid; | ||
1626 | D_ID matchdid; | ||
1627 | 1665 | ||
1628 | if (did == Bcast_DID) | 1666 | if (did == Bcast_DID) |
1629 | return 0; | 1667 | return 0; |
@@ -1637,7 +1675,7 @@ lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) | |||
1637 | return 1; | 1675 | return 1; |
1638 | 1676 | ||
1639 | /* Next check for area/domain identically equals 0 match */ | 1677 | /* Next check for area/domain identically equals 0 match */ |
1640 | mydid.un.word = phba->fc_myDID; | 1678 | mydid.un.word = vport->fc_myDID; |
1641 | if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) { | 1679 | if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) { |
1642 | return 0; | 1680 | return 0; |
1643 | } | 1681 | } |
@@ -1669,15 +1707,15 @@ lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) | |||
1669 | } | 1707 | } |
1670 | 1708 | ||
1671 | /* Search for a nodelist entry */ | 1709 | /* Search for a nodelist entry */ |
1672 | struct lpfc_nodelist * | 1710 | static struct lpfc_nodelist * |
1673 | lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did) | 1711 | __lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) |
1674 | { | 1712 | { |
1713 | struct lpfc_hba *phba = vport->phba; | ||
1675 | struct lpfc_nodelist *ndlp; | 1714 | struct lpfc_nodelist *ndlp; |
1676 | uint32_t data1; | 1715 | uint32_t data1; |
1677 | 1716 | ||
1678 | spin_lock_irq(phba->host->host_lock); | 1717 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
1679 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { | 1718 | if (lpfc_matchdid(vport, ndlp, did)) { |
1680 | if (lpfc_matchdid(phba, ndlp, did)) { | ||
1681 | data1 = (((uint32_t) ndlp->nlp_state << 24) | | 1719 | data1 = (((uint32_t) ndlp->nlp_state << 24) | |
1682 | ((uint32_t) ndlp->nlp_xri << 16) | | 1720 | ((uint32_t) ndlp->nlp_xri << 16) | |
1683 | ((uint32_t) ndlp->nlp_type << 8) | | 1721 | ((uint32_t) ndlp->nlp_type << 8) | |
@@ -1688,11 +1726,9 @@ lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did) | |||
1688 | phba->brd_no, | 1726 | phba->brd_no, |
1689 | ndlp, ndlp->nlp_DID, | 1727 | ndlp, ndlp->nlp_DID, |
1690 | ndlp->nlp_flag, data1); | 1728 | ndlp->nlp_flag, data1); |
1691 | spin_unlock_irq(phba->host->host_lock); | ||
1692 | return ndlp; | 1729 | return ndlp; |
1693 | } | 1730 | } |
1694 | } | 1731 | } |
1695 | spin_unlock_irq(phba->host->host_lock); | ||
1696 | 1732 | ||
1697 | /* FIND node did <did> NOT FOUND */ | 1733 | /* FIND node did <did> NOT FOUND */ |
1698 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | 1734 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, |
@@ -1702,68 +1738,85 @@ lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did) | |||
1702 | } | 1738 | } |
1703 | 1739 | ||
1704 | struct lpfc_nodelist * | 1740 | struct lpfc_nodelist * |
1705 | lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) | 1741 | lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) |
1742 | { | ||
1743 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1744 | struct lpfc_nodelist *ndlp; | ||
1745 | |||
1746 | spin_lock_irq(shost->host_lock); | ||
1747 | ndlp = __lpfc_findnode_did(vport, did); | ||
1748 | spin_unlock_irq(shost->host_lock); | ||
1749 | return ndlp; | ||
1750 | } | ||
1751 | |||
1752 | struct lpfc_nodelist * | ||
1753 | lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | ||
1706 | { | 1754 | { |
1755 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1707 | struct lpfc_nodelist *ndlp; | 1756 | struct lpfc_nodelist *ndlp; |
1708 | 1757 | ||
1709 | ndlp = lpfc_findnode_did(phba, did); | 1758 | ndlp = lpfc_findnode_did(vport, did); |
1710 | if (!ndlp) { | 1759 | if (!ndlp) { |
1711 | if ((phba->fc_flag & FC_RSCN_MODE) && | 1760 | if ((vport->fc_flag & FC_RSCN_MODE) != 0 && |
1712 | ((lpfc_rscn_payload_check(phba, did) == 0))) | 1761 | lpfc_rscn_payload_check(vport, did) == 0) |
1713 | return NULL; | 1762 | return NULL; |
1714 | ndlp = (struct lpfc_nodelist *) | 1763 | ndlp = (struct lpfc_nodelist *) |
1715 | mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | 1764 | mempool_alloc(vport->phba->nlp_mem_pool, GFP_KERNEL); |
1716 | if (!ndlp) | 1765 | if (!ndlp) |
1717 | return NULL; | 1766 | return NULL; |
1718 | lpfc_nlp_init(phba, ndlp, did); | 1767 | lpfc_nlp_init(vport, ndlp, did); |
1719 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1768 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1769 | spin_lock_irq(shost->host_lock); | ||
1720 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1770 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
1771 | spin_unlock_irq(shost->host_lock); | ||
1721 | return ndlp; | 1772 | return ndlp; |
1722 | } | 1773 | } |
1723 | if (phba->fc_flag & FC_RSCN_MODE) { | 1774 | if (vport->fc_flag & FC_RSCN_MODE) { |
1724 | if (lpfc_rscn_payload_check(phba, did)) { | 1775 | if (lpfc_rscn_payload_check(vport, did)) { |
1776 | spin_lock_irq(shost->host_lock); | ||
1725 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1777 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
1778 | spin_unlock_irq(shost->host_lock); | ||
1726 | 1779 | ||
1727 | /* Since this node is marked for discovery, | 1780 | /* Since this node is marked for discovery, |
1728 | * delay timeout is not needed. | 1781 | * delay timeout is not needed. |
1729 | */ | 1782 | */ |
1730 | if (ndlp->nlp_flag & NLP_DELAY_TMO) | 1783 | if (ndlp->nlp_flag & NLP_DELAY_TMO) |
1731 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1784 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1732 | } else | 1785 | } else |
1733 | ndlp = NULL; | 1786 | ndlp = NULL; |
1734 | } else { | 1787 | } else { |
1735 | if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE || | 1788 | if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE || |
1736 | ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) | 1789 | ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) |
1737 | return NULL; | 1790 | return NULL; |
1738 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1791 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1792 | spin_lock_irq(shost->host_lock); | ||
1739 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1793 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
1794 | spin_unlock_irq(shost->host_lock); | ||
1740 | } | 1795 | } |
1741 | return ndlp; | 1796 | return ndlp; |
1742 | } | 1797 | } |
1743 | 1798 | ||
1744 | /* Build a list of nodes to discover based on the loopmap */ | 1799 | /* Build a list of nodes to discover based on the loopmap */ |
1745 | void | 1800 | void |
1746 | lpfc_disc_list_loopmap(struct lpfc_hba * phba) | 1801 | lpfc_disc_list_loopmap(struct lpfc_vport *vport) |
1747 | { | 1802 | { |
1803 | struct lpfc_hba *phba = vport->phba; | ||
1748 | int j; | 1804 | int j; |
1749 | uint32_t alpa, index; | 1805 | uint32_t alpa, index; |
1750 | 1806 | ||
1751 | if (phba->hba_state <= LPFC_LINK_DOWN) { | 1807 | if (!lpfc_is_link_up(phba)) |
1752 | return; | 1808 | return; |
1753 | } | 1809 | |
1754 | if (phba->fc_topology != TOPOLOGY_LOOP) { | 1810 | if (phba->fc_topology != TOPOLOGY_LOOP) |
1755 | return; | 1811 | return; |
1756 | } | ||
1757 | 1812 | ||
1758 | /* Check for loop map present or not */ | 1813 | /* Check for loop map present or not */ |
1759 | if (phba->alpa_map[0]) { | 1814 | if (phba->alpa_map[0]) { |
1760 | for (j = 1; j <= phba->alpa_map[0]; j++) { | 1815 | for (j = 1; j <= phba->alpa_map[0]; j++) { |
1761 | alpa = phba->alpa_map[j]; | 1816 | alpa = phba->alpa_map[j]; |
1762 | 1817 | if (((vport->fc_myDID & 0xff) == alpa) || (alpa == 0)) | |
1763 | if (((phba->fc_myDID & 0xff) == alpa) || (alpa == 0)) { | ||
1764 | continue; | 1818 | continue; |
1765 | } | 1819 | lpfc_setup_disc_node(vport, alpa); |
1766 | lpfc_setup_disc_node(phba, alpa); | ||
1767 | } | 1820 | } |
1768 | } else { | 1821 | } else { |
1769 | /* No alpamap, so try all alpa's */ | 1822 | /* No alpamap, so try all alpa's */ |
@@ -1776,113 +1829,139 @@ lpfc_disc_list_loopmap(struct lpfc_hba * phba) | |||
1776 | else | 1829 | else |
1777 | index = FC_MAXLOOP - j - 1; | 1830 | index = FC_MAXLOOP - j - 1; |
1778 | alpa = lpfcAlpaArray[index]; | 1831 | alpa = lpfcAlpaArray[index]; |
1779 | if ((phba->fc_myDID & 0xff) == alpa) { | 1832 | if ((vport->fc_myDID & 0xff) == alpa) |
1780 | continue; | 1833 | continue; |
1781 | } | 1834 | lpfc_setup_disc_node(vport, alpa); |
1782 | |||
1783 | lpfc_setup_disc_node(phba, alpa); | ||
1784 | } | 1835 | } |
1785 | } | 1836 | } |
1786 | return; | 1837 | return; |
1787 | } | 1838 | } |
1788 | 1839 | ||
1789 | /* Start Link up / RSCN discovery on NPR list */ | ||
1790 | void | 1840 | void |
1791 | lpfc_disc_start(struct lpfc_hba * phba) | 1841 | lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport) |
1792 | { | 1842 | { |
1793 | struct lpfc_sli *psli; | ||
1794 | LPFC_MBOXQ_t *mbox; | 1843 | LPFC_MBOXQ_t *mbox; |
1844 | struct lpfc_sli *psli = &phba->sli; | ||
1845 | struct lpfc_sli_ring *extra_ring = &psli->ring[psli->extra_ring]; | ||
1846 | struct lpfc_sli_ring *fcp_ring = &psli->ring[psli->fcp_ring]; | ||
1847 | struct lpfc_sli_ring *next_ring = &psli->ring[psli->next_ring]; | ||
1848 | int rc; | ||
1849 | |||
1850 | /* Link up discovery */ | ||
1851 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) != NULL) { | ||
1852 | phba->link_state = LPFC_CLEAR_LA; | ||
1853 | lpfc_clear_la(phba, mbox); | ||
1854 | mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | ||
1855 | mbox->vport = vport; | ||
1856 | rc = lpfc_sli_issue_mbox(phba, mbox, (MBX_NOWAIT | | ||
1857 | MBX_STOP_IOCB)); | ||
1858 | if (rc == MBX_NOT_FINISHED) { | ||
1859 | mempool_free(mbox, phba->mbox_mem_pool); | ||
1860 | lpfc_disc_flush_list(vport); | ||
1861 | extra_ring->flag &= ~LPFC_STOP_IOCB_EVENT; | ||
1862 | fcp_ring->flag &= ~LPFC_STOP_IOCB_EVENT; | ||
1863 | next_ring->flag &= ~LPFC_STOP_IOCB_EVENT; | ||
1864 | vport->port_state = LPFC_VPORT_READY; | ||
1865 | } | ||
1866 | } | ||
1867 | } | ||
1868 | |||
1869 | /* Start Link up / RSCN discovery on NPR nodes */ | ||
1870 | void | ||
1871 | lpfc_disc_start(struct lpfc_vport *vport) | ||
1872 | { | ||
1873 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1874 | struct lpfc_hba *phba = vport->phba; | ||
1795 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1875 | struct lpfc_nodelist *ndlp, *next_ndlp; |
1796 | uint32_t num_sent; | 1876 | uint32_t num_sent; |
1797 | uint32_t clear_la_pending; | 1877 | uint32_t clear_la_pending; |
1798 | int did_changed; | 1878 | int did_changed; |
1799 | int rc; | ||
1800 | |||
1801 | psli = &phba->sli; | ||
1802 | 1879 | ||
1803 | if (phba->hba_state <= LPFC_LINK_DOWN) { | 1880 | if (!lpfc_is_link_up(phba)) |
1804 | return; | 1881 | return; |
1805 | } | 1882 | |
1806 | if (phba->hba_state == LPFC_CLEAR_LA) | 1883 | if (phba->link_state == LPFC_CLEAR_LA) |
1807 | clear_la_pending = 1; | 1884 | clear_la_pending = 1; |
1808 | else | 1885 | else |
1809 | clear_la_pending = 0; | 1886 | clear_la_pending = 0; |
1810 | 1887 | ||
1811 | if (phba->hba_state < LPFC_HBA_READY) { | 1888 | if (vport->port_state < LPFC_VPORT_READY) |
1812 | phba->hba_state = LPFC_DISC_AUTH; | 1889 | vport->port_state = LPFC_DISC_AUTH; |
1813 | } | ||
1814 | lpfc_set_disctmo(phba); | ||
1815 | 1890 | ||
1816 | if (phba->fc_prevDID == phba->fc_myDID) { | 1891 | lpfc_set_disctmo(vport); |
1892 | |||
1893 | if (vport->fc_prevDID == vport->fc_myDID) | ||
1817 | did_changed = 0; | 1894 | did_changed = 0; |
1818 | } else { | 1895 | else |
1819 | did_changed = 1; | 1896 | did_changed = 1; |
1820 | } | 1897 | |
1821 | phba->fc_prevDID = phba->fc_myDID; | 1898 | vport->fc_prevDID = vport->fc_myDID; |
1822 | phba->num_disc_nodes = 0; | 1899 | vport->num_disc_nodes = 0; |
1823 | 1900 | ||
1824 | /* Start Discovery state <hba_state> */ | 1901 | /* Start Discovery state <hba_state> */ |
1825 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 1902 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
1826 | "%d:0202 Start Discovery hba state x%x " | 1903 | "%d:0202 Start Discovery hba state x%x " |
1827 | "Data: x%x x%x x%x\n", | 1904 | "Data: x%x x%x x%x\n", |
1828 | phba->brd_no, phba->hba_state, phba->fc_flag, | 1905 | phba->brd_no, vport->port_state, vport->fc_flag, |
1829 | phba->fc_plogi_cnt, phba->fc_adisc_cnt); | 1906 | vport->fc_plogi_cnt, vport->fc_adisc_cnt); |
1830 | 1907 | ||
1831 | /* If our did changed, we MUST do PLOGI */ | 1908 | /* If our did changed, we MUST do PLOGI */ |
1832 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { | 1909 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
1833 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && | 1910 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && |
1834 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && | 1911 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && |
1835 | did_changed) { | 1912 | did_changed) { |
1836 | spin_lock_irq(phba->host->host_lock); | 1913 | spin_lock_irq(shost->host_lock); |
1837 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1914 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1838 | spin_unlock_irq(phba->host->host_lock); | 1915 | spin_unlock_irq(shost->host_lock); |
1839 | } | 1916 | } |
1840 | } | 1917 | } |
1841 | 1918 | ||
1842 | /* First do ADISCs - if any */ | 1919 | /* First do ADISCs - if any */ |
1843 | num_sent = lpfc_els_disc_adisc(phba); | 1920 | num_sent = lpfc_els_disc_adisc(vport); |
1844 | 1921 | ||
1845 | if (num_sent) | 1922 | if (num_sent) |
1846 | return; | 1923 | return; |
1847 | 1924 | ||
1848 | if ((phba->hba_state < LPFC_HBA_READY) && (!clear_la_pending)) { | 1925 | if (vport->port_state < LPFC_VPORT_READY && !clear_la_pending) { |
1926 | if (vport->port_type == LPFC_PHYSICAL_PORT) { | ||
1849 | /* If we get here, there is nothing to ADISC */ | 1927 | /* If we get here, there is nothing to ADISC */ |
1850 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { | 1928 | printk(KERN_ERR "%s (%d): do clear_la\n", |
1851 | phba->hba_state = LPFC_CLEAR_LA; | 1929 | __FUNCTION__, __LINE__); |
1852 | lpfc_clear_la(phba, mbox); | 1930 | lpfc_issue_clear_la(phba, vport); |
1853 | mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 1931 | } else if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) { |
1854 | rc = lpfc_sli_issue_mbox(phba, mbox, | 1932 | |
1855 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 1933 | vport->num_disc_nodes = 0; |
1856 | if (rc == MBX_NOT_FINISHED) { | 1934 | /* go thru NPR nodes and issue ELS PLOGIs */ |
1857 | mempool_free( mbox, phba->mbox_mem_pool); | 1935 | if (vport->fc_npr_cnt) |
1858 | lpfc_disc_flush_list(phba); | 1936 | lpfc_els_disc_plogi(vport); |
1859 | psli->ring[(psli->extra_ring)].flag &= | 1937 | |
1860 | ~LPFC_STOP_IOCB_EVENT; | 1938 | if (!vport->num_disc_nodes) { |
1861 | psli->ring[(psli->fcp_ring)].flag &= | 1939 | spin_lock_irq(shost->host_lock); |
1862 | ~LPFC_STOP_IOCB_EVENT; | 1940 | vport->fc_flag &= ~FC_NDISC_ACTIVE; |
1863 | psli->ring[(psli->next_ring)].flag &= | 1941 | spin_unlock_irq(shost->host_lock); |
1864 | ~LPFC_STOP_IOCB_EVENT; | ||
1865 | phba->hba_state = LPFC_HBA_READY; | ||
1866 | } | 1942 | } |
1943 | printk(KERN_ERR "%s (%d): vport ready\n", | ||
1944 | __FUNCTION__, __LINE__); | ||
1945 | vport->port_state = LPFC_VPORT_READY; | ||
1867 | } | 1946 | } |
1868 | } else { | 1947 | } else { |
1869 | /* Next do PLOGIs - if any */ | 1948 | /* Next do PLOGIs - if any */ |
1870 | num_sent = lpfc_els_disc_plogi(phba); | 1949 | num_sent = lpfc_els_disc_plogi(vport); |
1871 | 1950 | ||
1872 | if (num_sent) | 1951 | if (num_sent) |
1873 | return; | 1952 | return; |
1874 | 1953 | ||
1875 | if (phba->fc_flag & FC_RSCN_MODE) { | 1954 | if (vport->fc_flag & FC_RSCN_MODE) { |
1876 | /* Check to see if more RSCNs came in while we | 1955 | /* Check to see if more RSCNs came in while we |
1877 | * were processing this one. | 1956 | * were processing this one. |
1878 | */ | 1957 | */ |
1879 | if ((phba->fc_rscn_id_cnt == 0) && | 1958 | if ((vport->fc_rscn_id_cnt == 0) && |
1880 | (!(phba->fc_flag & FC_RSCN_DISCOVERY))) { | 1959 | (!(vport->fc_flag & FC_RSCN_DISCOVERY))) { |
1881 | spin_lock_irq(phba->host->host_lock); | 1960 | spin_lock_irq(shost->host_lock); |
1882 | phba->fc_flag &= ~FC_RSCN_MODE; | 1961 | vport->fc_flag &= ~FC_RSCN_MODE; |
1883 | spin_unlock_irq(phba->host->host_lock); | 1962 | spin_unlock_irq(shost->host_lock); |
1884 | } else | 1963 | } else |
1885 | lpfc_els_handle_rscn(phba); | 1964 | lpfc_els_handle_rscn(vport); |
1886 | } | 1965 | } |
1887 | } | 1966 | } |
1888 | return; | 1967 | return; |
@@ -1893,7 +1972,7 @@ lpfc_disc_start(struct lpfc_hba * phba) | |||
1893 | * ring the match the sppecified nodelist. | 1972 | * ring the match the sppecified nodelist. |
1894 | */ | 1973 | */ |
1895 | static void | 1974 | static void |
1896 | lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1975 | lpfc_free_tx(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) |
1897 | { | 1976 | { |
1898 | LIST_HEAD(completions); | 1977 | LIST_HEAD(completions); |
1899 | struct lpfc_sli *psli; | 1978 | struct lpfc_sli *psli; |
@@ -1907,7 +1986,7 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1907 | /* Error matching iocb on txq or txcmplq | 1986 | /* Error matching iocb on txq or txcmplq |
1908 | * First check the txq. | 1987 | * First check the txq. |
1909 | */ | 1988 | */ |
1910 | spin_lock_irq(phba->host->host_lock); | 1989 | spin_lock_irq(&phba->hbalock); |
1911 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { | 1990 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { |
1912 | if (iocb->context1 != ndlp) { | 1991 | if (iocb->context1 != ndlp) { |
1913 | continue; | 1992 | continue; |
@@ -1927,36 +2006,36 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1927 | continue; | 2006 | continue; |
1928 | } | 2007 | } |
1929 | icmd = &iocb->iocb; | 2008 | icmd = &iocb->iocb; |
1930 | if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || | 2009 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR || |
1931 | (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { | 2010 | icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX) { |
1932 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); | 2011 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
1933 | } | 2012 | } |
1934 | } | 2013 | } |
1935 | spin_unlock_irq(phba->host->host_lock); | 2014 | spin_unlock_irq(&phba->hbalock); |
1936 | 2015 | ||
1937 | while (!list_empty(&completions)) { | 2016 | while (!list_empty(&completions)) { |
1938 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | 2017 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); |
1939 | list_del(&iocb->list); | 2018 | list_del(&iocb->list); |
1940 | 2019 | ||
1941 | if (iocb->iocb_cmpl) { | 2020 | if (!iocb->iocb_cmpl) |
2021 | lpfc_sli_release_iocbq(phba, iocb); | ||
2022 | else { | ||
1942 | icmd = &iocb->iocb; | 2023 | icmd = &iocb->iocb; |
1943 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 2024 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
1944 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | 2025 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
1945 | (iocb->iocb_cmpl) (phba, iocb, iocb); | 2026 | (iocb->iocb_cmpl) (phba, iocb, iocb); |
1946 | } else | 2027 | } |
1947 | lpfc_sli_release_iocbq(phba, iocb); | ||
1948 | } | 2028 | } |
1949 | |||
1950 | return; | ||
1951 | } | 2029 | } |
1952 | 2030 | ||
1953 | void | 2031 | void |
1954 | lpfc_disc_flush_list(struct lpfc_hba * phba) | 2032 | lpfc_disc_flush_list(struct lpfc_vport *vport) |
1955 | { | 2033 | { |
1956 | struct lpfc_nodelist *ndlp, *next_ndlp; | 2034 | struct lpfc_nodelist *ndlp, *next_ndlp; |
2035 | struct lpfc_hba *phba = vport->phba; | ||
1957 | 2036 | ||
1958 | if (phba->fc_plogi_cnt || phba->fc_adisc_cnt) { | 2037 | if (vport->fc_plogi_cnt || vport->fc_adisc_cnt) { |
1959 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, | 2038 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, |
1960 | nlp_listp) { | 2039 | nlp_listp) { |
1961 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || | 2040 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || |
1962 | ndlp->nlp_state == NLP_STE_ADISC_ISSUE) { | 2041 | ndlp->nlp_state == NLP_STE_ADISC_ISSUE) { |
@@ -1985,47 +2064,51 @@ lpfc_disc_flush_list(struct lpfc_hba * phba) | |||
1985 | void | 2064 | void |
1986 | lpfc_disc_timeout(unsigned long ptr) | 2065 | lpfc_disc_timeout(unsigned long ptr) |
1987 | { | 2066 | { |
1988 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; | 2067 | struct lpfc_vport *vport = (struct lpfc_vport *) ptr; |
2068 | struct lpfc_hba *phba = vport->phba; | ||
1989 | unsigned long flags = 0; | 2069 | unsigned long flags = 0; |
1990 | 2070 | ||
1991 | if (unlikely(!phba)) | 2071 | if (unlikely(!phba)) |
1992 | return; | 2072 | return; |
1993 | 2073 | ||
1994 | spin_lock_irqsave(phba->host->host_lock, flags); | 2074 | if ((vport->work_port_events & WORKER_DISC_TMO) == 0) { |
1995 | if (!(phba->work_hba_events & WORKER_DISC_TMO)) { | 2075 | spin_lock_irqsave(&vport->work_port_lock, flags); |
1996 | phba->work_hba_events |= WORKER_DISC_TMO; | 2076 | vport->work_port_events |= WORKER_DISC_TMO; |
2077 | spin_unlock_irqrestore(&vport->work_port_lock, flags); | ||
2078 | |||
1997 | if (phba->work_wait) | 2079 | if (phba->work_wait) |
1998 | wake_up(phba->work_wait); | 2080 | wake_up(phba->work_wait); |
1999 | } | 2081 | } |
2000 | spin_unlock_irqrestore(phba->host->host_lock, flags); | ||
2001 | return; | 2082 | return; |
2002 | } | 2083 | } |
2003 | 2084 | ||
2004 | static void | 2085 | static void |
2005 | lpfc_disc_timeout_handler(struct lpfc_hba *phba) | 2086 | lpfc_disc_timeout_handler(struct lpfc_vport *vport) |
2006 | { | 2087 | { |
2007 | struct lpfc_sli *psli; | 2088 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
2089 | struct lpfc_hba *phba = vport->phba; | ||
2090 | struct lpfc_sli *psli = &phba->sli; | ||
2008 | struct lpfc_nodelist *ndlp, *next_ndlp; | 2091 | struct lpfc_nodelist *ndlp, *next_ndlp; |
2009 | LPFC_MBOXQ_t *clearlambox, *initlinkmbox; | 2092 | LPFC_MBOXQ_t *clearlambox, *initlinkmbox; |
2010 | int rc, clrlaerr = 0; | 2093 | int rc, clrlaerr = 0; |
2011 | 2094 | ||
2012 | if (unlikely(!phba)) | 2095 | if (!(vport->fc_flag & FC_DISC_TMO)) |
2013 | return; | 2096 | return; |
2014 | 2097 | ||
2015 | if (!(phba->fc_flag & FC_DISC_TMO)) | ||
2016 | return; | ||
2017 | |||
2018 | psli = &phba->sli; | ||
2019 | 2098 | ||
2020 | spin_lock_irq(phba->host->host_lock); | 2099 | spin_lock_irq(shost->host_lock); |
2021 | phba->fc_flag &= ~FC_DISC_TMO; | 2100 | vport->fc_flag &= ~FC_DISC_TMO; |
2022 | spin_unlock_irq(phba->host->host_lock); | 2101 | spin_unlock_irq(shost->host_lock); |
2023 | 2102 | ||
2024 | switch (phba->hba_state) { | 2103 | printk(KERN_ERR "%s (%d): link_state = %d, port_state = %d\n", |
2104 | __FUNCTION__, __LINE__, phba->link_state, vport->port_state); | ||
2105 | switch (vport->port_state) { | ||
2025 | 2106 | ||
2026 | case LPFC_LOCAL_CFG_LINK: | 2107 | case LPFC_LOCAL_CFG_LINK: |
2027 | /* hba_state is identically LPFC_LOCAL_CFG_LINK while waiting for FAN */ | 2108 | /* port_state is identically LPFC_LOCAL_CFG_LINK while waiting for |
2028 | /* FAN timeout */ | 2109 | * FAN |
2110 | */ | ||
2111 | /* FAN timeout */ | ||
2029 | lpfc_printf_log(phba, | 2112 | lpfc_printf_log(phba, |
2030 | KERN_WARNING, | 2113 | KERN_WARNING, |
2031 | LOG_DISCOVERY, | 2114 | LOG_DISCOVERY, |
@@ -2033,27 +2116,27 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2033 | phba->brd_no); | 2116 | phba->brd_no); |
2034 | 2117 | ||
2035 | /* Start discovery by sending FLOGI, clean up old rpis */ | 2118 | /* Start discovery by sending FLOGI, clean up old rpis */ |
2036 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, | 2119 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, |
2037 | nlp_listp) { | 2120 | nlp_listp) { |
2038 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) | 2121 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) |
2039 | continue; | 2122 | continue; |
2040 | if (ndlp->nlp_type & NLP_FABRIC) { | 2123 | if (ndlp->nlp_type & NLP_FABRIC) { |
2041 | /* Clean up the ndlp on Fabric connections */ | 2124 | /* Clean up the ndlp on Fabric connections */ |
2042 | lpfc_drop_node(phba, ndlp); | 2125 | lpfc_drop_node(vport, ndlp); |
2043 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 2126 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { |
2044 | /* Fail outstanding IO now since device | 2127 | /* Fail outstanding IO now since device |
2045 | * is marked for PLOGI. | 2128 | * is marked for PLOGI. |
2046 | */ | 2129 | */ |
2047 | lpfc_unreg_rpi(phba, ndlp); | 2130 | lpfc_unreg_rpi(vport, ndlp); |
2048 | } | 2131 | } |
2049 | } | 2132 | } |
2050 | phba->hba_state = LPFC_FLOGI; | 2133 | vport->port_state = LPFC_FLOGI; |
2051 | lpfc_set_disctmo(phba); | 2134 | lpfc_set_disctmo(vport); |
2052 | lpfc_initial_flogi(phba); | 2135 | lpfc_initial_flogi(vport); |
2053 | break; | 2136 | break; |
2054 | 2137 | ||
2055 | case LPFC_FLOGI: | 2138 | case LPFC_FLOGI: |
2056 | /* hba_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */ | 2139 | /* port_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */ |
2057 | /* Initial FLOGI timeout */ | 2140 | /* Initial FLOGI timeout */ |
2058 | lpfc_printf_log(phba, | 2141 | lpfc_printf_log(phba, |
2059 | KERN_ERR, | 2142 | KERN_ERR, |
@@ -2066,10 +2149,10 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2066 | */ | 2149 | */ |
2067 | 2150 | ||
2068 | /* FLOGI failed, so just use loop map to make discovery list */ | 2151 | /* FLOGI failed, so just use loop map to make discovery list */ |
2069 | lpfc_disc_list_loopmap(phba); | 2152 | lpfc_disc_list_loopmap(vport); |
2070 | 2153 | ||
2071 | /* Start discovery */ | 2154 | /* Start discovery */ |
2072 | lpfc_disc_start(phba); | 2155 | lpfc_disc_start(vport); |
2073 | break; | 2156 | break; |
2074 | 2157 | ||
2075 | case LPFC_FABRIC_CFG_LINK: | 2158 | case LPFC_FABRIC_CFG_LINK: |
@@ -2080,11 +2163,11 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2080 | "login\n", phba->brd_no); | 2163 | "login\n", phba->brd_no); |
2081 | 2164 | ||
2082 | /* Next look for NameServer ndlp */ | 2165 | /* Next look for NameServer ndlp */ |
2083 | ndlp = lpfc_findnode_did(phba, NameServer_DID); | 2166 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
2084 | if (ndlp) | 2167 | if (ndlp) |
2085 | lpfc_nlp_put(ndlp); | 2168 | lpfc_nlp_put(ndlp); |
2086 | /* Start discovery */ | 2169 | /* Start discovery */ |
2087 | lpfc_disc_start(phba); | 2170 | lpfc_disc_start(vport); |
2088 | break; | 2171 | break; |
2089 | 2172 | ||
2090 | case LPFC_NS_QRY: | 2173 | case LPFC_NS_QRY: |
@@ -2093,17 +2176,17 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2093 | "%d:0224 NameServer Query timeout " | 2176 | "%d:0224 NameServer Query timeout " |
2094 | "Data: x%x x%x\n", | 2177 | "Data: x%x x%x\n", |
2095 | phba->brd_no, | 2178 | phba->brd_no, |
2096 | phba->fc_ns_retry, LPFC_MAX_NS_RETRY); | 2179 | vport->fc_ns_retry, LPFC_MAX_NS_RETRY); |
2097 | 2180 | ||
2098 | ndlp = lpfc_findnode_did(phba, NameServer_DID); | 2181 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
2099 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 2182 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { |
2100 | if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) { | 2183 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { |
2101 | /* Try it one more time */ | 2184 | /* Try it one more time */ |
2102 | rc = lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT); | 2185 | rc = lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT); |
2103 | if (rc == 0) | 2186 | if (rc == 0) |
2104 | break; | 2187 | break; |
2105 | } | 2188 | } |
2106 | phba->fc_ns_retry = 0; | 2189 | vport->fc_ns_retry = 0; |
2107 | } | 2190 | } |
2108 | 2191 | ||
2109 | /* Nothing to authenticate, so CLEAR_LA right now */ | 2192 | /* Nothing to authenticate, so CLEAR_LA right now */ |
@@ -2114,13 +2197,16 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2114 | "%d:0226 Device Discovery " | 2197 | "%d:0226 Device Discovery " |
2115 | "completion error\n", | 2198 | "completion error\n", |
2116 | phba->brd_no); | 2199 | phba->brd_no); |
2117 | phba->hba_state = LPFC_HBA_ERROR; | 2200 | phba->link_state = LPFC_HBA_ERROR; |
2118 | break; | 2201 | break; |
2119 | } | 2202 | } |
2120 | 2203 | ||
2121 | phba->hba_state = LPFC_CLEAR_LA; | 2204 | phba->link_state = LPFC_CLEAR_LA; |
2122 | lpfc_clear_la(phba, clearlambox); | 2205 | lpfc_clear_la(phba, clearlambox); |
2206 | printk(KERN_ERR "%s (%d): do clear_la\n", | ||
2207 | __FUNCTION__, __LINE__); | ||
2123 | clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 2208 | clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
2209 | clearlambox->vport = vport; | ||
2124 | rc = lpfc_sli_issue_mbox(phba, clearlambox, | 2210 | rc = lpfc_sli_issue_mbox(phba, clearlambox, |
2125 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 2211 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
2126 | if (rc == MBX_NOT_FINISHED) { | 2212 | if (rc == MBX_NOT_FINISHED) { |
@@ -2136,7 +2222,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2136 | "%d:0206 Device Discovery " | 2222 | "%d:0206 Device Discovery " |
2137 | "completion error\n", | 2223 | "completion error\n", |
2138 | phba->brd_no); | 2224 | phba->brd_no); |
2139 | phba->hba_state = LPFC_HBA_ERROR; | 2225 | phba->link_state = LPFC_HBA_ERROR; |
2140 | break; | 2226 | break; |
2141 | } | 2227 | } |
2142 | 2228 | ||
@@ -2159,7 +2245,8 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2159 | LOG_DISCOVERY, | 2245 | LOG_DISCOVERY, |
2160 | "%d:0227 Node Authentication timeout\n", | 2246 | "%d:0227 Node Authentication timeout\n", |
2161 | phba->brd_no); | 2247 | phba->brd_no); |
2162 | lpfc_disc_flush_list(phba); | 2248 | lpfc_disc_flush_list(vport); |
2249 | |||
2163 | clearlambox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 2250 | clearlambox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
2164 | if (!clearlambox) { | 2251 | if (!clearlambox) { |
2165 | clrlaerr = 1; | 2252 | clrlaerr = 1; |
@@ -2167,12 +2254,15 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2167 | "%d:0207 Device Discovery " | 2254 | "%d:0207 Device Discovery " |
2168 | "completion error\n", | 2255 | "completion error\n", |
2169 | phba->brd_no); | 2256 | phba->brd_no); |
2170 | phba->hba_state = LPFC_HBA_ERROR; | 2257 | phba->link_state = LPFC_HBA_ERROR; |
2171 | break; | 2258 | break; |
2172 | } | 2259 | } |
2173 | phba->hba_state = LPFC_CLEAR_LA; | 2260 | phba->link_state = LPFC_CLEAR_LA; |
2174 | lpfc_clear_la(phba, clearlambox); | 2261 | lpfc_clear_la(phba, clearlambox); |
2262 | printk(KERN_ERR "%s (%d): do clear_la\n", | ||
2263 | __FUNCTION__, __LINE__); | ||
2175 | clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 2264 | clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
2265 | clearlambox->vport = vport; | ||
2176 | rc = lpfc_sli_issue_mbox(phba, clearlambox, | 2266 | rc = lpfc_sli_issue_mbox(phba, clearlambox, |
2177 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 2267 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
2178 | if (rc == MBX_NOT_FINISHED) { | 2268 | if (rc == MBX_NOT_FINISHED) { |
@@ -2181,40 +2271,73 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2181 | } | 2271 | } |
2182 | break; | 2272 | break; |
2183 | 2273 | ||
2184 | case LPFC_CLEAR_LA: | 2274 | case LPFC_VPORT_READY: |
2185 | /* CLEAR LA timeout */ | 2275 | if (vport->fc_flag & FC_RSCN_MODE) { |
2186 | lpfc_printf_log(phba, | ||
2187 | KERN_ERR, | ||
2188 | LOG_DISCOVERY, | ||
2189 | "%d:0228 CLEAR LA timeout\n", | ||
2190 | phba->brd_no); | ||
2191 | clrlaerr = 1; | ||
2192 | break; | ||
2193 | |||
2194 | case LPFC_HBA_READY: | ||
2195 | if (phba->fc_flag & FC_RSCN_MODE) { | ||
2196 | lpfc_printf_log(phba, | 2276 | lpfc_printf_log(phba, |
2197 | KERN_ERR, | 2277 | KERN_ERR, |
2198 | LOG_DISCOVERY, | 2278 | LOG_DISCOVERY, |
2199 | "%d:0231 RSCN timeout Data: x%x x%x\n", | 2279 | "%d:0231 RSCN timeout Data: x%x x%x\n", |
2200 | phba->brd_no, | 2280 | phba->brd_no, |
2201 | phba->fc_ns_retry, LPFC_MAX_NS_RETRY); | 2281 | vport->fc_ns_retry, LPFC_MAX_NS_RETRY); |
2202 | 2282 | ||
2203 | /* Cleanup any outstanding ELS commands */ | 2283 | /* Cleanup any outstanding ELS commands */ |
2204 | lpfc_els_flush_cmd(phba); | 2284 | lpfc_els_flush_cmd(vport); |
2205 | 2285 | ||
2206 | lpfc_els_flush_rscn(phba); | 2286 | lpfc_els_flush_rscn(vport); |
2207 | lpfc_disc_flush_list(phba); | 2287 | lpfc_disc_flush_list(vport); |
2208 | } | 2288 | } |
2209 | break; | 2289 | break; |
2290 | |||
2291 | case LPFC_STATE_UNKNOWN: | ||
2292 | case LPFC_NS_REG: | ||
2293 | case LPFC_BUILD_DISC_LIST: | ||
2294 | lpfc_printf_log(phba, | ||
2295 | KERN_ERR, | ||
2296 | LOG_DISCOVERY, | ||
2297 | "%d:0229 Unexpected discovery timeout, vport " | ||
2298 | "State x%x\n", | ||
2299 | vport->port_state, | ||
2300 | phba->brd_no); | ||
2301 | |||
2302 | break; | ||
2303 | } | ||
2304 | |||
2305 | switch (phba->link_state) { | ||
2306 | case LPFC_CLEAR_LA: | ||
2307 | /* CLEAR LA timeout */ | ||
2308 | lpfc_printf_log(phba, | ||
2309 | KERN_ERR, | ||
2310 | LOG_DISCOVERY, | ||
2311 | "%d:0228 CLEAR LA timeout\n", | ||
2312 | phba->brd_no); | ||
2313 | clrlaerr = 1; | ||
2314 | break; | ||
2315 | |||
2316 | case LPFC_LINK_UNKNOWN: | ||
2317 | case LPFC_WARM_START: | ||
2318 | case LPFC_INIT_START: | ||
2319 | case LPFC_INIT_MBX_CMDS: | ||
2320 | case LPFC_LINK_DOWN: | ||
2321 | case LPFC_LINK_UP: | ||
2322 | case LPFC_HBA_ERROR: | ||
2323 | lpfc_printf_log(phba, | ||
2324 | KERN_ERR, | ||
2325 | LOG_DISCOVERY, | ||
2326 | "%d:0230 Unexpected timeout, hba link " | ||
2327 | "state x%x\n", | ||
2328 | phba->brd_no, phba->link_state); | ||
2329 | clrlaerr = 1; | ||
2330 | break; | ||
2210 | } | 2331 | } |
2211 | 2332 | ||
2212 | if (clrlaerr) { | 2333 | if (clrlaerr) { |
2213 | lpfc_disc_flush_list(phba); | 2334 | lpfc_disc_flush_list(vport); |
2214 | psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 2335 | psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
2215 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 2336 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
2216 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 2337 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
2217 | phba->hba_state = LPFC_HBA_READY; | 2338 | printk(KERN_ERR "%s (%d): vport ready\n", |
2339 | __FUNCTION__, __LINE__); | ||
2340 | vport->port_state = LPFC_VPORT_READY; | ||
2218 | } | 2341 | } |
2219 | 2342 | ||
2220 | return; | 2343 | return; |
@@ -2227,37 +2350,29 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2227 | * handed off to the SLI layer. | 2350 | * handed off to the SLI layer. |
2228 | */ | 2351 | */ |
2229 | void | 2352 | void |
2230 | lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 2353 | lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
2231 | { | 2354 | { |
2232 | struct lpfc_sli *psli; | 2355 | MAILBOX_t *mb = &pmb->mb; |
2233 | MAILBOX_t *mb; | 2356 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
2234 | struct lpfc_dmabuf *mp; | 2357 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
2235 | struct lpfc_nodelist *ndlp; | 2358 | struct lpfc_vport *vport = pmb->vport; |
2236 | |||
2237 | psli = &phba->sli; | ||
2238 | mb = &pmb->mb; | ||
2239 | |||
2240 | ndlp = (struct lpfc_nodelist *) pmb->context2; | ||
2241 | mp = (struct lpfc_dmabuf *) (pmb->context1); | ||
2242 | 2359 | ||
2243 | pmb->context1 = NULL; | 2360 | pmb->context1 = NULL; |
2244 | 2361 | ||
2245 | ndlp->nlp_rpi = mb->un.varWords[0]; | 2362 | ndlp->nlp_rpi = mb->un.varWords[0]; |
2246 | ndlp->nlp_type |= NLP_FABRIC; | 2363 | ndlp->nlp_type |= NLP_FABRIC; |
2247 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 2364 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
2248 | 2365 | ||
2249 | /* Start issuing Fabric-Device Management Interface (FDMI) | 2366 | /* |
2250 | * command to 0xfffffa (FDMI well known port) | 2367 | * Start issuing Fabric-Device Management Interface (FDMI) command to |
2368 | * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if | ||
2369 | * fdmi-on=2 (supporting RPA/hostnmae) | ||
2251 | */ | 2370 | */ |
2252 | if (phba->cfg_fdmi_on == 1) { | 2371 | |
2253 | lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA); | 2372 | if (phba->cfg_fdmi_on == 1) |
2254 | } else { | 2373 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); |
2255 | /* | 2374 | else |
2256 | * Delay issuing FDMI command if fdmi-on=2 | 2375 | mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); |
2257 | * (supporting RPA/hostnmae) | ||
2258 | */ | ||
2259 | mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); | ||
2260 | } | ||
2261 | 2376 | ||
2262 | /* Mailbox took a reference to the node */ | 2377 | /* Mailbox took a reference to the node */ |
2263 | lpfc_nlp_put(ndlp); | 2378 | lpfc_nlp_put(ndlp); |
@@ -2283,16 +2398,12 @@ lpfc_filter_by_wwpn(struct lpfc_nodelist *ndlp, void *param) | |||
2283 | sizeof(ndlp->nlp_portname)) == 0; | 2398 | sizeof(ndlp->nlp_portname)) == 0; |
2284 | } | 2399 | } |
2285 | 2400 | ||
2286 | /* | ||
2287 | * Search node lists for a remote port matching filter criteria | ||
2288 | * Caller needs to hold host_lock before calling this routine. | ||
2289 | */ | ||
2290 | struct lpfc_nodelist * | 2401 | struct lpfc_nodelist * |
2291 | __lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param) | 2402 | __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) |
2292 | { | 2403 | { |
2293 | struct lpfc_nodelist *ndlp; | 2404 | struct lpfc_nodelist *ndlp; |
2294 | 2405 | ||
2295 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { | 2406 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
2296 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE && | 2407 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE && |
2297 | filter(ndlp, param)) | 2408 | filter(ndlp, param)) |
2298 | return ndlp; | 2409 | return ndlp; |
@@ -2305,54 +2416,58 @@ __lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param) | |||
2305 | * This routine is used when the caller does NOT have host_lock. | 2416 | * This routine is used when the caller does NOT have host_lock. |
2306 | */ | 2417 | */ |
2307 | struct lpfc_nodelist * | 2418 | struct lpfc_nodelist * |
2308 | lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param) | 2419 | lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) |
2309 | { | 2420 | { |
2421 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2310 | struct lpfc_nodelist *ndlp; | 2422 | struct lpfc_nodelist *ndlp; |
2311 | 2423 | ||
2312 | spin_lock_irq(phba->host->host_lock); | 2424 | spin_lock_irq(shost->host_lock); |
2313 | ndlp = __lpfc_find_node(phba, filter, param); | 2425 | ndlp = __lpfc_find_node(vport, filter, param); |
2314 | spin_unlock_irq(phba->host->host_lock); | 2426 | spin_unlock_irq(shost->host_lock); |
2315 | return ndlp; | 2427 | return ndlp; |
2316 | } | 2428 | } |
2317 | 2429 | ||
2318 | /* | 2430 | /* |
2319 | * This routine looks up the ndlp lists for the given RPI. If rpi found it | 2431 | * This routine looks up the ndlp lists for the given RPI. If rpi found it |
2320 | * returns the node list pointer else return NULL. | 2432 | * returns the node list element pointer else return NULL. |
2321 | */ | 2433 | */ |
2322 | struct lpfc_nodelist * | 2434 | struct lpfc_nodelist * |
2323 | __lpfc_findnode_rpi(struct lpfc_hba *phba, uint16_t rpi) | 2435 | __lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) |
2324 | { | 2436 | { |
2325 | return __lpfc_find_node(phba, lpfc_filter_by_rpi, &rpi); | 2437 | return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); |
2326 | } | 2438 | } |
2327 | 2439 | ||
2328 | struct lpfc_nodelist * | 2440 | struct lpfc_nodelist * |
2329 | lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) | 2441 | lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) |
2330 | { | 2442 | { |
2443 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2331 | struct lpfc_nodelist *ndlp; | 2444 | struct lpfc_nodelist *ndlp; |
2332 | 2445 | ||
2333 | spin_lock_irq(phba->host->host_lock); | 2446 | spin_lock_irq(shost->host_lock); |
2334 | ndlp = __lpfc_findnode_rpi(phba, rpi); | 2447 | ndlp = __lpfc_findnode_rpi(vport, rpi); |
2335 | spin_unlock_irq(phba->host->host_lock); | 2448 | spin_unlock_irq(shost->host_lock); |
2336 | return ndlp; | 2449 | return ndlp; |
2337 | } | 2450 | } |
2338 | 2451 | ||
2339 | /* | 2452 | /* |
2340 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it | 2453 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it |
2341 | * returns the node list pointer else return NULL. | 2454 | * returns the node element list pointer else return NULL. |
2342 | */ | 2455 | */ |
2343 | struct lpfc_nodelist * | 2456 | struct lpfc_nodelist * |
2344 | lpfc_findnode_wwpn(struct lpfc_hba *phba, struct lpfc_name *wwpn) | 2457 | lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn) |
2345 | { | 2458 | { |
2459 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2346 | struct lpfc_nodelist *ndlp; | 2460 | struct lpfc_nodelist *ndlp; |
2347 | 2461 | ||
2348 | spin_lock_irq(phba->host->host_lock); | 2462 | spin_lock_irq(shost->host_lock); |
2349 | ndlp = __lpfc_find_node(phba, lpfc_filter_by_wwpn, wwpn); | 2463 | ndlp = __lpfc_find_node(vport, lpfc_filter_by_wwpn, wwpn); |
2350 | spin_unlock_irq(phba->host->host_lock); | 2464 | spin_unlock_irq(shost->host_lock); |
2351 | return NULL; | 2465 | return NULL; |
2352 | } | 2466 | } |
2353 | 2467 | ||
2354 | void | 2468 | void |
2355 | lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) | 2469 | lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
2470 | uint32_t did) | ||
2356 | { | 2471 | { |
2357 | memset(ndlp, 0, sizeof (struct lpfc_nodelist)); | 2472 | memset(ndlp, 0, sizeof (struct lpfc_nodelist)); |
2358 | INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); | 2473 | INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); |
@@ -2360,7 +2475,7 @@ lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) | |||
2360 | ndlp->nlp_delayfunc.function = lpfc_els_retry_delay; | 2475 | ndlp->nlp_delayfunc.function = lpfc_els_retry_delay; |
2361 | ndlp->nlp_delayfunc.data = (unsigned long)ndlp; | 2476 | ndlp->nlp_delayfunc.data = (unsigned long)ndlp; |
2362 | ndlp->nlp_DID = did; | 2477 | ndlp->nlp_DID = did; |
2363 | ndlp->nlp_phba = phba; | 2478 | ndlp->vport = vport; |
2364 | ndlp->nlp_sid = NLP_NO_SID; | 2479 | ndlp->nlp_sid = NLP_NO_SID; |
2365 | INIT_LIST_HEAD(&ndlp->nlp_listp); | 2480 | INIT_LIST_HEAD(&ndlp->nlp_listp); |
2366 | kref_init(&ndlp->kref); | 2481 | kref_init(&ndlp->kref); |
@@ -2372,8 +2487,8 @@ lpfc_nlp_release(struct kref *kref) | |||
2372 | { | 2487 | { |
2373 | struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, | 2488 | struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, |
2374 | kref); | 2489 | kref); |
2375 | lpfc_nlp_remove(ndlp->nlp_phba, ndlp); | 2490 | lpfc_nlp_remove(ndlp->vport, ndlp); |
2376 | mempool_free(ndlp, ndlp->nlp_phba->nlp_mem_pool); | 2491 | mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool); |
2377 | } | 2492 | } |
2378 | 2493 | ||
2379 | struct lpfc_nodelist * | 2494 | struct lpfc_nodelist * |
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 2623a9bc777..c4be6dc00c4 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -312,8 +312,7 @@ struct csp { | |||
312 | 312 | ||
313 | #ifdef __BIG_ENDIAN_BITFIELD | 313 | #ifdef __BIG_ENDIAN_BITFIELD |
314 | uint16_t increasingOffset:1; /* FC Word 1, bit 31 */ | 314 | uint16_t increasingOffset:1; /* FC Word 1, bit 31 */ |
315 | uint16_t randomOffset:1; /* FC Word 1, bit 30 */ | 315 | uint16_t response_multiple_Nport:1; /* FC Word 1, bit 29 */ |
316 | uint16_t word1Reserved2:1; /* FC Word 1, bit 29 */ | ||
317 | uint16_t fPort:1; /* FC Word 1, bit 28 */ | 316 | uint16_t fPort:1; /* FC Word 1, bit 28 */ |
318 | uint16_t altBbCredit:1; /* FC Word 1, bit 27 */ | 317 | uint16_t altBbCredit:1; /* FC Word 1, bit 27 */ |
319 | uint16_t edtovResolution:1; /* FC Word 1, bit 26 */ | 318 | uint16_t edtovResolution:1; /* FC Word 1, bit 26 */ |
@@ -2178,8 +2177,8 @@ typedef struct { | |||
2178 | #define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */ | 2177 | #define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */ |
2179 | #define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */ | 2178 | #define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */ |
2180 | 2179 | ||
2181 | /* Structure for MB Command CONFIG_PORT (0x88) */ | ||
2182 | 2180 | ||
2181 | /* Structure for MB Command CONFIG_PORT (0x88) */ | ||
2183 | typedef struct { | 2182 | typedef struct { |
2184 | uint32_t pcbLen; | 2183 | uint32_t pcbLen; |
2185 | uint32_t pcbLow; /* bit 31:0 of memory based port config block */ | 2184 | uint32_t pcbLow; /* bit 31:0 of memory based port config block */ |
@@ -2742,15 +2741,15 @@ struct lpfc_sli2_slim { | |||
2742 | IOCB_t IOCBs[MAX_SLI2_IOCB]; | 2741 | IOCB_t IOCBs[MAX_SLI2_IOCB]; |
2743 | }; | 2742 | }; |
2744 | 2743 | ||
2745 | /******************************************************************* | 2744 | /* |
2746 | This macro check PCI device to allow special handling for LC HBAs. | 2745 | * This function checks PCI device to allow special handling for LC HBAs. |
2747 | 2746 | * | |
2748 | Parameters: | 2747 | * Parameters: |
2749 | device : struct pci_dev 's device field | 2748 | * device : struct pci_dev 's device field |
2750 | 2749 | * | |
2751 | return 1 => TRUE | 2750 | * return 1 => TRUE |
2752 | 0 => FALSE | 2751 | * 0 => FALSE |
2753 | *******************************************************************/ | 2752 | */ |
2754 | static inline int | 2753 | static inline int |
2755 | lpfc_is_LC_HBA(unsigned short device) | 2754 | lpfc_is_LC_HBA(unsigned short device) |
2756 | { | 2755 | { |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index dcb4ba0ecee..e11c4cda0f3 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -49,6 +49,8 @@ static int lpfc_post_rcv_buf(struct lpfc_hba *); | |||
49 | static struct scsi_transport_template *lpfc_transport_template = NULL; | 49 | static struct scsi_transport_template *lpfc_transport_template = NULL; |
50 | static DEFINE_IDR(lpfc_hba_index); | 50 | static DEFINE_IDR(lpfc_hba_index); |
51 | 51 | ||
52 | |||
53 | |||
52 | /************************************************************************/ | 54 | /************************************************************************/ |
53 | /* */ | 55 | /* */ |
54 | /* lpfc_config_port_prep */ | 56 | /* lpfc_config_port_prep */ |
@@ -61,7 +63,7 @@ static DEFINE_IDR(lpfc_hba_index); | |||
61 | /* */ | 63 | /* */ |
62 | /************************************************************************/ | 64 | /************************************************************************/ |
63 | int | 65 | int |
64 | lpfc_config_port_prep(struct lpfc_hba * phba) | 66 | lpfc_config_port_prep(struct lpfc_hba *phba) |
65 | { | 67 | { |
66 | lpfc_vpd_t *vp = &phba->vpd; | 68 | lpfc_vpd_t *vp = &phba->vpd; |
67 | int i = 0, rc; | 69 | int i = 0, rc; |
@@ -75,12 +77,12 @@ lpfc_config_port_prep(struct lpfc_hba * phba) | |||
75 | 77 | ||
76 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 78 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
77 | if (!pmb) { | 79 | if (!pmb) { |
78 | phba->hba_state = LPFC_HBA_ERROR; | 80 | phba->link_state = LPFC_HBA_ERROR; |
79 | return -ENOMEM; | 81 | return -ENOMEM; |
80 | } | 82 | } |
81 | 83 | ||
82 | mb = &pmb->mb; | 84 | mb = &pmb->mb; |
83 | phba->hba_state = LPFC_INIT_MBX_CMDS; | 85 | phba->link_state = LPFC_INIT_MBX_CMDS; |
84 | 86 | ||
85 | if (lpfc_is_LC_HBA(phba->pcidev->device)) { | 87 | if (lpfc_is_LC_HBA(phba->pcidev->device)) { |
86 | if (init_key) { | 88 | if (init_key) { |
@@ -112,7 +114,9 @@ lpfc_config_port_prep(struct lpfc_hba * phba) | |||
112 | return -ERESTART; | 114 | return -ERESTART; |
113 | } | 115 | } |
114 | memcpy(phba->wwnn, (char *)mb->un.varRDnvp.nodename, | 116 | memcpy(phba->wwnn, (char *)mb->un.varRDnvp.nodename, |
115 | sizeof (mb->un.varRDnvp.nodename)); | 117 | sizeof(phba->wwnn)); |
118 | memcpy(phba->wwpn, (char *)mb->un.varRDnvp.portname, | ||
119 | sizeof(phba->wwpn)); | ||
116 | } | 120 | } |
117 | 121 | ||
118 | /* Setup and issue mailbox READ REV command */ | 122 | /* Setup and issue mailbox READ REV command */ |
@@ -212,37 +216,24 @@ out_free_mbox: | |||
212 | /* */ | 216 | /* */ |
213 | /************************************************************************/ | 217 | /************************************************************************/ |
214 | int | 218 | int |
215 | lpfc_config_port_post(struct lpfc_hba * phba) | 219 | lpfc_config_port_post(struct lpfc_hba *phba) |
216 | { | 220 | { |
221 | struct lpfc_vport *vport = phba->pport; | ||
217 | LPFC_MBOXQ_t *pmb; | 222 | LPFC_MBOXQ_t *pmb; |
218 | MAILBOX_t *mb; | 223 | MAILBOX_t *mb; |
219 | struct lpfc_dmabuf *mp; | 224 | struct lpfc_dmabuf *mp; |
220 | struct lpfc_sli *psli = &phba->sli; | 225 | struct lpfc_sli *psli = &phba->sli; |
221 | uint32_t status, timeout; | 226 | uint32_t status, timeout; |
222 | int i, j, rc; | 227 | int i, j; |
228 | int rc; | ||
223 | 229 | ||
224 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 230 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
225 | if (!pmb) { | 231 | if (!pmb) { |
226 | phba->hba_state = LPFC_HBA_ERROR; | 232 | phba->link_state = LPFC_HBA_ERROR; |
227 | return -ENOMEM; | 233 | return -ENOMEM; |
228 | } | 234 | } |
229 | mb = &pmb->mb; | 235 | mb = &pmb->mb; |
230 | 236 | ||
231 | lpfc_config_link(phba, pmb); | ||
232 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | ||
233 | if (rc != MBX_SUCCESS) { | ||
234 | lpfc_printf_log(phba, | ||
235 | KERN_ERR, | ||
236 | LOG_INIT, | ||
237 | "%d:0447 Adapter failed init, mbxCmd x%x " | ||
238 | "CONFIG_LINK mbxStatus x%x\n", | ||
239 | phba->brd_no, | ||
240 | mb->mbxCommand, mb->mbxStatus); | ||
241 | phba->hba_state = LPFC_HBA_ERROR; | ||
242 | mempool_free( pmb, phba->mbox_mem_pool); | ||
243 | return -EIO; | ||
244 | } | ||
245 | |||
246 | /* Get login parameters for NID. */ | 237 | /* Get login parameters for NID. */ |
247 | lpfc_read_sparam(phba, pmb); | 238 | lpfc_read_sparam(phba, pmb); |
248 | if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { | 239 | if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { |
@@ -253,7 +244,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
253 | "READ_SPARM mbxStatus x%x\n", | 244 | "READ_SPARM mbxStatus x%x\n", |
254 | phba->brd_no, | 245 | phba->brd_no, |
255 | mb->mbxCommand, mb->mbxStatus); | 246 | mb->mbxCommand, mb->mbxStatus); |
256 | phba->hba_state = LPFC_HBA_ERROR; | 247 | phba->link_state = LPFC_HBA_ERROR; |
257 | mp = (struct lpfc_dmabuf *) pmb->context1; | 248 | mp = (struct lpfc_dmabuf *) pmb->context1; |
258 | mempool_free( pmb, phba->mbox_mem_pool); | 249 | mempool_free( pmb, phba->mbox_mem_pool); |
259 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 250 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
@@ -263,25 +254,27 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
263 | 254 | ||
264 | mp = (struct lpfc_dmabuf *) pmb->context1; | 255 | mp = (struct lpfc_dmabuf *) pmb->context1; |
265 | 256 | ||
266 | memcpy(&phba->fc_sparam, mp->virt, sizeof (struct serv_parm)); | 257 | memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm)); |
267 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 258 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
268 | kfree(mp); | 259 | kfree(mp); |
269 | pmb->context1 = NULL; | 260 | pmb->context1 = NULL; |
270 | 261 | ||
271 | if (phba->cfg_soft_wwnn) | 262 | if (phba->cfg_soft_wwnn) |
272 | u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn); | 263 | u64_to_wwn(phba->cfg_soft_wwnn, |
264 | vport->fc_sparam.nodeName.u.wwn); | ||
273 | if (phba->cfg_soft_wwpn) | 265 | if (phba->cfg_soft_wwpn) |
274 | u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn); | 266 | u64_to_wwn(phba->cfg_soft_wwpn, |
275 | memcpy(&phba->fc_nodename, &phba->fc_sparam.nodeName, | 267 | vport->fc_sparam.portName.u.wwn); |
268 | memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName, | ||
276 | sizeof (struct lpfc_name)); | 269 | sizeof (struct lpfc_name)); |
277 | memcpy(&phba->fc_portname, &phba->fc_sparam.portName, | 270 | memcpy(&vport->fc_portname, &vport->fc_sparam.portName, |
278 | sizeof (struct lpfc_name)); | 271 | sizeof (struct lpfc_name)); |
279 | /* If no serial number in VPD data, use low 6 bytes of WWNN */ | 272 | /* If no serial number in VPD data, use low 6 bytes of WWNN */ |
280 | /* This should be consolidated into parse_vpd ? - mr */ | 273 | /* This should be consolidated into parse_vpd ? - mr */ |
281 | if (phba->SerialNumber[0] == 0) { | 274 | if (phba->SerialNumber[0] == 0) { |
282 | uint8_t *outptr; | 275 | uint8_t *outptr; |
283 | 276 | ||
284 | outptr = &phba->fc_nodename.u.s.IEEE[0]; | 277 | outptr = &vport->fc_nodename.u.s.IEEE[0]; |
285 | for (i = 0; i < 12; i++) { | 278 | for (i = 0; i < 12; i++) { |
286 | status = *outptr++; | 279 | status = *outptr++; |
287 | j = ((status & 0xf0) >> 4); | 280 | j = ((status & 0xf0) >> 4); |
@@ -311,7 +304,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
311 | "READ_CONFIG, mbxStatus x%x\n", | 304 | "READ_CONFIG, mbxStatus x%x\n", |
312 | phba->brd_no, | 305 | phba->brd_no, |
313 | mb->mbxCommand, mb->mbxStatus); | 306 | mb->mbxCommand, mb->mbxStatus); |
314 | phba->hba_state = LPFC_HBA_ERROR; | 307 | phba->link_state = LPFC_HBA_ERROR; |
315 | mempool_free( pmb, phba->mbox_mem_pool); | 308 | mempool_free( pmb, phba->mbox_mem_pool); |
316 | return -EIO; | 309 | return -EIO; |
317 | } | 310 | } |
@@ -348,7 +341,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
348 | phba->cfg_link_speed = LINK_SPEED_AUTO; | 341 | phba->cfg_link_speed = LINK_SPEED_AUTO; |
349 | } | 342 | } |
350 | 343 | ||
351 | phba->hba_state = LPFC_LINK_DOWN; | 344 | phba->link_state = LPFC_LINK_DOWN; |
352 | 345 | ||
353 | /* Only process IOCBs on ring 0 till hba_state is READY */ | 346 | /* Only process IOCBs on ring 0 till hba_state is READY */ |
354 | if (psli->ring[psli->extra_ring].cmdringaddr) | 347 | if (psli->ring[psli->extra_ring].cmdringaddr) |
@@ -362,7 +355,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
362 | lpfc_post_rcv_buf(phba); | 355 | lpfc_post_rcv_buf(phba); |
363 | 356 | ||
364 | /* Enable appropriate host interrupts */ | 357 | /* Enable appropriate host interrupts */ |
365 | spin_lock_irq(phba->host->host_lock); | 358 | spin_lock_irq(&phba->hbalock); |
366 | status = readl(phba->HCregaddr); | 359 | status = readl(phba->HCregaddr); |
367 | status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA; | 360 | status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA; |
368 | if (psli->num_rings > 0) | 361 | if (psli->num_rings > 0) |
@@ -380,13 +373,13 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
380 | 373 | ||
381 | writel(status, phba->HCregaddr); | 374 | writel(status, phba->HCregaddr); |
382 | readl(phba->HCregaddr); /* flush */ | 375 | readl(phba->HCregaddr); /* flush */ |
383 | spin_unlock_irq(phba->host->host_lock); | 376 | spin_unlock_irq(&phba->hbalock); |
384 | 377 | ||
385 | /* | 378 | /* |
386 | * Setup the ring 0 (els) timeout handler | 379 | * Setup the ring 0 (els) timeout handler |
387 | */ | 380 | */ |
388 | timeout = phba->fc_ratov << 1; | 381 | timeout = phba->fc_ratov << 1; |
389 | mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); | 382 | mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); |
390 | 383 | ||
391 | lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); | 384 | lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); |
392 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 385 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
@@ -408,7 +401,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
408 | writel(0xffffffff, phba->HAregaddr); | 401 | writel(0xffffffff, phba->HAregaddr); |
409 | readl(phba->HAregaddr); /* flush */ | 402 | readl(phba->HAregaddr); /* flush */ |
410 | 403 | ||
411 | phba->hba_state = LPFC_HBA_ERROR; | 404 | phba->link_state = LPFC_HBA_ERROR; |
412 | if (rc != MBX_BUSY) | 405 | if (rc != MBX_BUSY) |
413 | mempool_free(pmb, phba->mbox_mem_pool); | 406 | mempool_free(pmb, phba->mbox_mem_pool); |
414 | return -EIO; | 407 | return -EIO; |
@@ -429,18 +422,20 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
429 | /* */ | 422 | /* */ |
430 | /************************************************************************/ | 423 | /************************************************************************/ |
431 | int | 424 | int |
432 | lpfc_hba_down_prep(struct lpfc_hba * phba) | 425 | lpfc_hba_down_prep(struct lpfc_hba *phba) |
433 | { | 426 | { |
427 | struct lpfc_vport *vport = phba->pport; | ||
428 | |||
434 | /* Disable interrupts */ | 429 | /* Disable interrupts */ |
435 | writel(0, phba->HCregaddr); | 430 | writel(0, phba->HCregaddr); |
436 | readl(phba->HCregaddr); /* flush */ | 431 | readl(phba->HCregaddr); /* flush */ |
437 | 432 | ||
438 | /* Cleanup potential discovery resources */ | 433 | /* Cleanup potential discovery resources */ |
439 | lpfc_els_flush_rscn(phba); | 434 | lpfc_els_flush_rscn(vport); |
440 | lpfc_els_flush_cmd(phba); | 435 | lpfc_els_flush_cmd(vport); |
441 | lpfc_disc_flush_list(phba); | 436 | lpfc_disc_flush_list(vport); |
442 | 437 | ||
443 | return (0); | 438 | return 0; |
444 | } | 439 | } |
445 | 440 | ||
446 | /************************************************************************/ | 441 | /************************************************************************/ |
@@ -453,7 +448,7 @@ lpfc_hba_down_prep(struct lpfc_hba * phba) | |||
453 | /* */ | 448 | /* */ |
454 | /************************************************************************/ | 449 | /************************************************************************/ |
455 | int | 450 | int |
456 | lpfc_hba_down_post(struct lpfc_hba * phba) | 451 | lpfc_hba_down_post(struct lpfc_hba *phba) |
457 | { | 452 | { |
458 | struct lpfc_sli *psli = &phba->sli; | 453 | struct lpfc_sli *psli = &phba->sli; |
459 | struct lpfc_sli_ring *pring; | 454 | struct lpfc_sli_ring *pring; |
@@ -486,11 +481,14 @@ lpfc_hba_down_post(struct lpfc_hba * phba) | |||
486 | /* */ | 481 | /* */ |
487 | /************************************************************************/ | 482 | /************************************************************************/ |
488 | void | 483 | void |
489 | lpfc_handle_eratt(struct lpfc_hba * phba) | 484 | lpfc_handle_eratt(struct lpfc_hba *phba) |
490 | { | 485 | { |
491 | struct lpfc_sli *psli = &phba->sli; | 486 | struct lpfc_vport *vport = phba->pport; |
487 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
488 | struct lpfc_sli *psli = &phba->sli; | ||
492 | struct lpfc_sli_ring *pring; | 489 | struct lpfc_sli_ring *pring; |
493 | uint32_t event_data; | 490 | uint32_t event_data; |
491 | |||
494 | /* If the pci channel is offline, ignore possible errors, | 492 | /* If the pci channel is offline, ignore possible errors, |
495 | * since we cannot communicate with the pci card anyway. */ | 493 | * since we cannot communicate with the pci card anyway. */ |
496 | if (pci_channel_offline(phba->pcidev)) | 494 | if (pci_channel_offline(phba->pcidev)) |
@@ -504,10 +502,10 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
504 | "Data: x%x x%x x%x\n", | 502 | "Data: x%x x%x x%x\n", |
505 | phba->brd_no, phba->work_hs, | 503 | phba->brd_no, phba->work_hs, |
506 | phba->work_status[0], phba->work_status[1]); | 504 | phba->work_status[0], phba->work_status[1]); |
507 | spin_lock_irq(phba->host->host_lock); | 505 | spin_lock_irq(shost->host_lock); |
508 | phba->fc_flag |= FC_ESTABLISH_LINK; | 506 | vport->fc_flag |= FC_ESTABLISH_LINK; |
509 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 507 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
510 | spin_unlock_irq(phba->host->host_lock); | 508 | spin_unlock_irq(shost->host_lock); |
511 | 509 | ||
512 | /* | 510 | /* |
513 | * Firmware stops when it triggled erratt with HS_FFER6. | 511 | * Firmware stops when it triggled erratt with HS_FFER6. |
@@ -544,7 +542,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
544 | phba->work_status[0], phba->work_status[1]); | 542 | phba->work_status[0], phba->work_status[1]); |
545 | 543 | ||
546 | event_data = FC_REG_DUMP_EVENT; | 544 | event_data = FC_REG_DUMP_EVENT; |
547 | fc_host_post_vendor_event(phba->host, fc_get_event_number(), | 545 | fc_host_post_vendor_event(shost, fc_get_event_number(), |
548 | sizeof(event_data), (char *) &event_data, | 546 | sizeof(event_data), (char *) &event_data, |
549 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | 547 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); |
550 | 548 | ||
@@ -552,7 +550,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
552 | lpfc_offline_prep(phba); | 550 | lpfc_offline_prep(phba); |
553 | lpfc_offline(phba); | 551 | lpfc_offline(phba); |
554 | lpfc_unblock_mgmt_io(phba); | 552 | lpfc_unblock_mgmt_io(phba); |
555 | phba->hba_state = LPFC_HBA_ERROR; | 553 | phba->link_state = LPFC_HBA_ERROR; |
556 | lpfc_hba_down_post(phba); | 554 | lpfc_hba_down_post(phba); |
557 | } | 555 | } |
558 | } | 556 | } |
@@ -566,9 +564,10 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
566 | /* */ | 564 | /* */ |
567 | /************************************************************************/ | 565 | /************************************************************************/ |
568 | void | 566 | void |
569 | lpfc_handle_latt(struct lpfc_hba * phba) | 567 | lpfc_handle_latt(struct lpfc_hba *phba) |
570 | { | 568 | { |
571 | struct lpfc_sli *psli = &phba->sli; | 569 | struct lpfc_vport *vport = phba->pport; |
570 | struct lpfc_sli *psli = &phba->sli; | ||
572 | LPFC_MBOXQ_t *pmb; | 571 | LPFC_MBOXQ_t *pmb; |
573 | volatile uint32_t control; | 572 | volatile uint32_t control; |
574 | struct lpfc_dmabuf *mp; | 573 | struct lpfc_dmabuf *mp; |
@@ -589,20 +588,21 @@ lpfc_handle_latt(struct lpfc_hba * phba) | |||
589 | rc = -EIO; | 588 | rc = -EIO; |
590 | 589 | ||
591 | /* Cleanup any outstanding ELS commands */ | 590 | /* Cleanup any outstanding ELS commands */ |
592 | lpfc_els_flush_cmd(phba); | 591 | lpfc_els_flush_cmd(vport); |
593 | 592 | ||
594 | psli->slistat.link_event++; | 593 | psli->slistat.link_event++; |
595 | lpfc_read_la(phba, pmb, mp); | 594 | lpfc_read_la(phba, pmb, mp); |
596 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; | 595 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; |
596 | pmb->vport = vport; | ||
597 | rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); | 597 | rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); |
598 | if (rc == MBX_NOT_FINISHED) | 598 | if (rc == MBX_NOT_FINISHED) |
599 | goto lpfc_handle_latt_free_mbuf; | 599 | goto lpfc_handle_latt_free_mbuf; |
600 | 600 | ||
601 | /* Clear Link Attention in HA REG */ | 601 | /* Clear Link Attention in HA REG */ |
602 | spin_lock_irq(phba->host->host_lock); | 602 | spin_lock_irq(&phba->hbalock); |
603 | writel(HA_LATT, phba->HAregaddr); | 603 | writel(HA_LATT, phba->HAregaddr); |
604 | readl(phba->HAregaddr); /* flush */ | 604 | readl(phba->HAregaddr); /* flush */ |
605 | spin_unlock_irq(phba->host->host_lock); | 605 | spin_unlock_irq(&phba->hbalock); |
606 | 606 | ||
607 | return; | 607 | return; |
608 | 608 | ||
@@ -614,7 +614,7 @@ lpfc_handle_latt_free_pmb: | |||
614 | mempool_free(pmb, phba->mbox_mem_pool); | 614 | mempool_free(pmb, phba->mbox_mem_pool); |
615 | lpfc_handle_latt_err_exit: | 615 | lpfc_handle_latt_err_exit: |
616 | /* Enable Link attention interrupts */ | 616 | /* Enable Link attention interrupts */ |
617 | spin_lock_irq(phba->host->host_lock); | 617 | spin_lock_irq(&phba->hbalock); |
618 | psli->sli_flag |= LPFC_PROCESS_LA; | 618 | psli->sli_flag |= LPFC_PROCESS_LA; |
619 | control = readl(phba->HCregaddr); | 619 | control = readl(phba->HCregaddr); |
620 | control |= HC_LAINT_ENA; | 620 | control |= HC_LAINT_ENA; |
@@ -624,9 +624,9 @@ lpfc_handle_latt_err_exit: | |||
624 | /* Clear Link Attention in HA REG */ | 624 | /* Clear Link Attention in HA REG */ |
625 | writel(HA_LATT, phba->HAregaddr); | 625 | writel(HA_LATT, phba->HAregaddr); |
626 | readl(phba->HAregaddr); /* flush */ | 626 | readl(phba->HAregaddr); /* flush */ |
627 | spin_unlock_irq(phba->host->host_lock); | 627 | spin_unlock_irq(&phba->hbalock); |
628 | lpfc_linkdown(phba); | 628 | lpfc_linkdown(phba); |
629 | phba->hba_state = LPFC_HBA_ERROR; | 629 | phba->link_state = LPFC_HBA_ERROR; |
630 | 630 | ||
631 | /* The other case is an error from issue_mbox */ | 631 | /* The other case is an error from issue_mbox */ |
632 | if (rc == -ENOMEM) | 632 | if (rc == -ENOMEM) |
@@ -646,7 +646,7 @@ lpfc_handle_latt_err_exit: | |||
646 | /* */ | 646 | /* */ |
647 | /************************************************************************/ | 647 | /************************************************************************/ |
648 | static int | 648 | static int |
649 | lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) | 649 | lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len) |
650 | { | 650 | { |
651 | uint8_t lenlo, lenhi; | 651 | uint8_t lenlo, lenhi; |
652 | int Length; | 652 | int Length; |
@@ -785,7 +785,7 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) | |||
785 | } | 785 | } |
786 | 786 | ||
787 | static void | 787 | static void |
788 | lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | 788 | lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) |
789 | { | 789 | { |
790 | lpfc_vpd_t *vp; | 790 | lpfc_vpd_t *vp; |
791 | uint16_t dev_id = phba->pcidev->device; | 791 | uint16_t dev_id = phba->pcidev->device; |
@@ -943,7 +943,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | |||
943 | /* Returns the number of buffers NOT posted. */ | 943 | /* Returns the number of buffers NOT posted. */ |
944 | /**************************************************/ | 944 | /**************************************************/ |
945 | int | 945 | int |
946 | lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | 946 | lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt, |
947 | int type) | 947 | int type) |
948 | { | 948 | { |
949 | IOCB_t *icmd; | 949 | IOCB_t *icmd; |
@@ -955,9 +955,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
955 | /* While there are buffers to post */ | 955 | /* While there are buffers to post */ |
956 | while (cnt > 0) { | 956 | while (cnt > 0) { |
957 | /* Allocate buffer for command iocb */ | 957 | /* Allocate buffer for command iocb */ |
958 | spin_lock_irq(phba->host->host_lock); | ||
959 | iocb = lpfc_sli_get_iocbq(phba); | 958 | iocb = lpfc_sli_get_iocbq(phba); |
960 | spin_unlock_irq(phba->host->host_lock); | ||
961 | if (iocb == NULL) { | 959 | if (iocb == NULL) { |
962 | pring->missbufcnt = cnt; | 960 | pring->missbufcnt = cnt; |
963 | return cnt; | 961 | return cnt; |
@@ -972,9 +970,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
972 | &mp1->phys); | 970 | &mp1->phys); |
973 | if (mp1 == 0 || mp1->virt == 0) { | 971 | if (mp1 == 0 || mp1->virt == 0) { |
974 | kfree(mp1); | 972 | kfree(mp1); |
975 | spin_lock_irq(phba->host->host_lock); | ||
976 | lpfc_sli_release_iocbq(phba, iocb); | 973 | lpfc_sli_release_iocbq(phba, iocb); |
977 | spin_unlock_irq(phba->host->host_lock); | ||
978 | pring->missbufcnt = cnt; | 974 | pring->missbufcnt = cnt; |
979 | return cnt; | 975 | return cnt; |
980 | } | 976 | } |
@@ -990,9 +986,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
990 | kfree(mp2); | 986 | kfree(mp2); |
991 | lpfc_mbuf_free(phba, mp1->virt, mp1->phys); | 987 | lpfc_mbuf_free(phba, mp1->virt, mp1->phys); |
992 | kfree(mp1); | 988 | kfree(mp1); |
993 | spin_lock_irq(phba->host->host_lock); | ||
994 | lpfc_sli_release_iocbq(phba, iocb); | 989 | lpfc_sli_release_iocbq(phba, iocb); |
995 | spin_unlock_irq(phba->host->host_lock); | ||
996 | pring->missbufcnt = cnt; | 990 | pring->missbufcnt = cnt; |
997 | return cnt; | 991 | return cnt; |
998 | } | 992 | } |
@@ -1018,7 +1012,6 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
1018 | icmd->ulpCommand = CMD_QUE_RING_BUF64_CN; | 1012 | icmd->ulpCommand = CMD_QUE_RING_BUF64_CN; |
1019 | icmd->ulpLe = 1; | 1013 | icmd->ulpLe = 1; |
1020 | 1014 | ||
1021 | spin_lock_irq(phba->host->host_lock); | ||
1022 | if (lpfc_sli_issue_iocb(phba, pring, iocb, 0) == IOCB_ERROR) { | 1015 | if (lpfc_sli_issue_iocb(phba, pring, iocb, 0) == IOCB_ERROR) { |
1023 | lpfc_mbuf_free(phba, mp1->virt, mp1->phys); | 1016 | lpfc_mbuf_free(phba, mp1->virt, mp1->phys); |
1024 | kfree(mp1); | 1017 | kfree(mp1); |
@@ -1030,10 +1023,8 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
1030 | } | 1023 | } |
1031 | lpfc_sli_release_iocbq(phba, iocb); | 1024 | lpfc_sli_release_iocbq(phba, iocb); |
1032 | pring->missbufcnt = cnt; | 1025 | pring->missbufcnt = cnt; |
1033 | spin_unlock_irq(phba->host->host_lock); | ||
1034 | return cnt; | 1026 | return cnt; |
1035 | } | 1027 | } |
1036 | spin_unlock_irq(phba->host->host_lock); | ||
1037 | lpfc_sli_ringpostbuf_put(phba, pring, mp1); | 1028 | lpfc_sli_ringpostbuf_put(phba, pring, mp1); |
1038 | if (mp2) { | 1029 | if (mp2) { |
1039 | lpfc_sli_ringpostbuf_put(phba, pring, mp2); | 1030 | lpfc_sli_ringpostbuf_put(phba, pring, mp2); |
@@ -1050,7 +1041,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
1050 | /* */ | 1041 | /* */ |
1051 | /************************************************************************/ | 1042 | /************************************************************************/ |
1052 | static int | 1043 | static int |
1053 | lpfc_post_rcv_buf(struct lpfc_hba * phba) | 1044 | lpfc_post_rcv_buf(struct lpfc_hba *phba) |
1054 | { | 1045 | { |
1055 | struct lpfc_sli *psli = &phba->sli; | 1046 | struct lpfc_sli *psli = &phba->sli; |
1056 | 1047 | ||
@@ -1151,7 +1142,7 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) | |||
1151 | { | 1142 | { |
1152 | int t; | 1143 | int t; |
1153 | uint32_t *HashWorking; | 1144 | uint32_t *HashWorking; |
1154 | uint32_t *pwwnn = phba->wwnn; | 1145 | uint32_t *pwwnn = (uint32_t *) phba->wwnn; |
1155 | 1146 | ||
1156 | HashWorking = kmalloc(80 * sizeof(uint32_t), GFP_KERNEL); | 1147 | HashWorking = kmalloc(80 * sizeof(uint32_t), GFP_KERNEL); |
1157 | if (!HashWorking) | 1148 | if (!HashWorking) |
@@ -1170,16 +1161,16 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) | |||
1170 | } | 1161 | } |
1171 | 1162 | ||
1172 | static void | 1163 | static void |
1173 | lpfc_cleanup(struct lpfc_hba * phba) | 1164 | lpfc_cleanup(struct lpfc_vport *vport) |
1174 | { | 1165 | { |
1175 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1166 | struct lpfc_nodelist *ndlp, *next_ndlp; |
1176 | 1167 | ||
1177 | /* clean up phba - lpfc specific */ | 1168 | /* clean up phba - lpfc specific */ |
1178 | lpfc_can_disctmo(phba); | 1169 | lpfc_can_disctmo(vport); |
1179 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) | 1170 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) |
1180 | lpfc_nlp_put(ndlp); | 1171 | lpfc_nlp_put(ndlp); |
1181 | 1172 | ||
1182 | INIT_LIST_HEAD(&phba->fc_nodes); | 1173 | INIT_LIST_HEAD(&vport->fc_nodes); |
1183 | 1174 | ||
1184 | return; | 1175 | return; |
1185 | } | 1176 | } |
@@ -1187,7 +1178,9 @@ lpfc_cleanup(struct lpfc_hba * phba) | |||
1187 | static void | 1178 | static void |
1188 | lpfc_establish_link_tmo(unsigned long ptr) | 1179 | lpfc_establish_link_tmo(unsigned long ptr) |
1189 | { | 1180 | { |
1190 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; | 1181 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; |
1182 | struct lpfc_vport *vport = phba->pport; | ||
1183 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1191 | unsigned long iflag; | 1184 | unsigned long iflag; |
1192 | 1185 | ||
1193 | 1186 | ||
@@ -1195,34 +1188,37 @@ lpfc_establish_link_tmo(unsigned long ptr) | |||
1195 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | 1188 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, |
1196 | "%d:1300 Re-establishing Link, timer expired " | 1189 | "%d:1300 Re-establishing Link, timer expired " |
1197 | "Data: x%x x%x\n", | 1190 | "Data: x%x x%x\n", |
1198 | phba->brd_no, phba->fc_flag, phba->hba_state); | 1191 | phba->brd_no, vport->fc_flag, |
1199 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1192 | vport->port_state); |
1200 | phba->fc_flag &= ~FC_ESTABLISH_LINK; | 1193 | spin_lock_irqsave(shost->host_lock, iflag); |
1201 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1194 | vport->fc_flag &= ~FC_ESTABLISH_LINK; |
1195 | spin_unlock_irqrestore(shost->host_lock, iflag); | ||
1202 | } | 1196 | } |
1203 | 1197 | ||
1204 | static int | 1198 | static void |
1205 | lpfc_stop_timer(struct lpfc_hba * phba) | 1199 | lpfc_stop_timer(struct lpfc_hba *phba) |
1206 | { | 1200 | { |
1207 | struct lpfc_sli *psli = &phba->sli; | 1201 | struct lpfc_vport *vport = phba->pport; |
1208 | 1202 | ||
1209 | del_timer_sync(&phba->fcp_poll_timer); | 1203 | del_timer_sync(&phba->fcp_poll_timer); |
1210 | del_timer_sync(&phba->fc_estabtmo); | 1204 | del_timer_sync(&phba->fc_estabtmo); |
1211 | del_timer_sync(&phba->fc_disctmo); | 1205 | del_timer_sync(&vport->els_tmofunc); |
1212 | del_timer_sync(&phba->fc_fdmitmo); | 1206 | del_timer_sync(&vport->fc_fdmitmo); |
1213 | del_timer_sync(&phba->els_tmofunc); | 1207 | del_timer_sync(&vport->fc_disctmo); |
1214 | psli = &phba->sli; | 1208 | del_timer_sync(&phba->sli.mbox_tmo); |
1215 | del_timer_sync(&psli->mbox_tmo); | 1209 | return; |
1216 | return(1); | ||
1217 | } | 1210 | } |
1218 | 1211 | ||
1219 | int | 1212 | int |
1220 | lpfc_online(struct lpfc_hba * phba) | 1213 | lpfc_online(struct lpfc_hba *phba) |
1221 | { | 1214 | { |
1215 | struct lpfc_vport *vport = phba->pport; | ||
1216 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1217 | |||
1222 | if (!phba) | 1218 | if (!phba) |
1223 | return 0; | 1219 | return 0; |
1224 | 1220 | ||
1225 | if (!(phba->fc_flag & FC_OFFLINE_MODE)) | 1221 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) |
1226 | return 0; | 1222 | return 0; |
1227 | 1223 | ||
1228 | lpfc_printf_log(phba, | 1224 | lpfc_printf_log(phba, |
@@ -1243,9 +1239,9 @@ lpfc_online(struct lpfc_hba * phba) | |||
1243 | return 1; | 1239 | return 1; |
1244 | } | 1240 | } |
1245 | 1241 | ||
1246 | spin_lock_irq(phba->host->host_lock); | 1242 | spin_lock_irq(shost->host_lock); |
1247 | phba->fc_flag &= ~FC_OFFLINE_MODE; | 1243 | vport->fc_flag &= ~FC_OFFLINE_MODE; |
1248 | spin_unlock_irq(phba->host->host_lock); | 1244 | spin_unlock_irq(shost->host_lock); |
1249 | 1245 | ||
1250 | lpfc_unblock_mgmt_io(phba); | 1246 | lpfc_unblock_mgmt_io(phba); |
1251 | return 0; | 1247 | return 0; |
@@ -1256,9 +1252,9 @@ lpfc_block_mgmt_io(struct lpfc_hba * phba) | |||
1256 | { | 1252 | { |
1257 | unsigned long iflag; | 1253 | unsigned long iflag; |
1258 | 1254 | ||
1259 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1255 | spin_lock_irqsave(&phba->hbalock, iflag); |
1260 | phba->fc_flag |= FC_BLOCK_MGMT_IO; | 1256 | phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO; |
1261 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1257 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1262 | } | 1258 | } |
1263 | 1259 | ||
1264 | void | 1260 | void |
@@ -1266,17 +1262,18 @@ lpfc_unblock_mgmt_io(struct lpfc_hba * phba) | |||
1266 | { | 1262 | { |
1267 | unsigned long iflag; | 1263 | unsigned long iflag; |
1268 | 1264 | ||
1269 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1265 | spin_lock_irqsave(&phba->hbalock, iflag); |
1270 | phba->fc_flag &= ~FC_BLOCK_MGMT_IO; | 1266 | phba->sli.sli_flag &= ~LPFC_BLOCK_MGMT_IO; |
1271 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1267 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1272 | } | 1268 | } |
1273 | 1269 | ||
1274 | void | 1270 | void |
1275 | lpfc_offline_prep(struct lpfc_hba * phba) | 1271 | lpfc_offline_prep(struct lpfc_hba * phba) |
1276 | { | 1272 | { |
1273 | struct lpfc_vport *vport = phba->pport; | ||
1277 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1274 | struct lpfc_nodelist *ndlp, *next_ndlp; |
1278 | 1275 | ||
1279 | if (phba->fc_flag & FC_OFFLINE_MODE) | 1276 | if (vport->fc_flag & FC_OFFLINE_MODE) |
1280 | return; | 1277 | return; |
1281 | 1278 | ||
1282 | lpfc_block_mgmt_io(phba); | 1279 | lpfc_block_mgmt_io(phba); |
@@ -1284,19 +1281,21 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
1284 | lpfc_linkdown(phba); | 1281 | lpfc_linkdown(phba); |
1285 | 1282 | ||
1286 | /* Issue an unreg_login to all nodes */ | 1283 | /* Issue an unreg_login to all nodes */ |
1287 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) | 1284 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) |
1288 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) | 1285 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) |
1289 | lpfc_unreg_rpi(phba, ndlp); | 1286 | lpfc_unreg_rpi(vport, ndlp); |
1290 | 1287 | ||
1291 | lpfc_sli_flush_mbox_queue(phba); | 1288 | lpfc_sli_flush_mbox_queue(phba); |
1292 | } | 1289 | } |
1293 | 1290 | ||
1294 | void | 1291 | void |
1295 | lpfc_offline(struct lpfc_hba * phba) | 1292 | lpfc_offline(struct lpfc_hba *phba) |
1296 | { | 1293 | { |
1294 | struct lpfc_vport *vport = phba->pport; | ||
1295 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1297 | unsigned long iflag; | 1296 | unsigned long iflag; |
1298 | 1297 | ||
1299 | if (phba->fc_flag & FC_OFFLINE_MODE) | 1298 | if (vport->fc_flag & FC_OFFLINE_MODE) |
1300 | return; | 1299 | return; |
1301 | 1300 | ||
1302 | /* stop all timers associated with this hba */ | 1301 | /* stop all timers associated with this hba */ |
@@ -1311,12 +1310,14 @@ lpfc_offline(struct lpfc_hba * phba) | |||
1311 | /* Bring down the SLI Layer and cleanup. The HBA is offline | 1310 | /* Bring down the SLI Layer and cleanup. The HBA is offline |
1312 | now. */ | 1311 | now. */ |
1313 | lpfc_sli_hba_down(phba); | 1312 | lpfc_sli_hba_down(phba); |
1314 | lpfc_cleanup(phba); | 1313 | lpfc_cleanup(vport); |
1315 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1314 | spin_lock_irqsave(shost->host_lock, iflag); |
1316 | phba->work_hba_events = 0; | 1315 | spin_lock(&phba->hbalock); |
1317 | phba->work_ha = 0; | 1316 | phba->work_ha = 0; |
1318 | phba->fc_flag |= FC_OFFLINE_MODE; | 1317 | vport->work_port_events = 0; |
1319 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1318 | vport->fc_flag |= FC_OFFLINE_MODE; |
1319 | spin_unlock(&phba->hbalock); | ||
1320 | spin_unlock_irqrestore(shost->host_lock, iflag); | ||
1320 | } | 1321 | } |
1321 | 1322 | ||
1322 | /****************************************************************************** | 1323 | /****************************************************************************** |
@@ -1326,12 +1327,12 @@ lpfc_offline(struct lpfc_hba * phba) | |||
1326 | * | 1327 | * |
1327 | ******************************************************************************/ | 1328 | ******************************************************************************/ |
1328 | static int | 1329 | static int |
1329 | lpfc_scsi_free(struct lpfc_hba * phba) | 1330 | lpfc_scsi_free(struct lpfc_hba *phba) |
1330 | { | 1331 | { |
1331 | struct lpfc_scsi_buf *sb, *sb_next; | 1332 | struct lpfc_scsi_buf *sb, *sb_next; |
1332 | struct lpfc_iocbq *io, *io_next; | 1333 | struct lpfc_iocbq *io, *io_next; |
1333 | 1334 | ||
1334 | spin_lock_irq(phba->host->host_lock); | 1335 | spin_lock_irq(&phba->hbalock); |
1335 | /* Release all the lpfc_scsi_bufs maintained by this host. */ | 1336 | /* Release all the lpfc_scsi_bufs maintained by this host. */ |
1336 | list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) { | 1337 | list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) { |
1337 | list_del(&sb->list); | 1338 | list_del(&sb->list); |
@@ -1348,130 +1349,158 @@ lpfc_scsi_free(struct lpfc_hba * phba) | |||
1348 | phba->total_iocbq_bufs--; | 1349 | phba->total_iocbq_bufs--; |
1349 | } | 1350 | } |
1350 | 1351 | ||
1351 | spin_unlock_irq(phba->host->host_lock); | 1352 | spin_unlock_irq(&phba->hbalock); |
1352 | 1353 | ||
1353 | return 0; | 1354 | return 0; |
1354 | } | 1355 | } |
1355 | 1356 | ||
1356 | void lpfc_remove_device(struct lpfc_hba *phba) | 1357 | struct lpfc_vport * |
1358 | lpfc_create_port(struct lpfc_hba *phba, int instance) | ||
1357 | { | 1359 | { |
1358 | unsigned long iflag; | 1360 | struct lpfc_vport *vport; |
1359 | 1361 | struct Scsi_Host *shost; | |
1360 | lpfc_free_sysfs_attr(phba); | 1362 | int error = 0; |
1361 | 1363 | ||
1362 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1364 | shost = scsi_host_alloc(&lpfc_template, sizeof(struct lpfc_vport)); |
1363 | phba->fc_flag |= FC_UNLOADING; | 1365 | if (!shost) |
1366 | goto out; | ||
1364 | 1367 | ||
1365 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1368 | vport = (struct lpfc_vport *) shost->hostdata; |
1369 | vport->phba = phba; | ||
1366 | 1370 | ||
1367 | fc_remove_host(phba->host); | 1371 | vport->load_flag |= FC_LOADING; |
1368 | scsi_remove_host(phba->host); | ||
1369 | |||
1370 | kthread_stop(phba->worker_thread); | ||
1371 | 1372 | ||
1373 | shost->unique_id = instance; | ||
1374 | shost->max_id = LPFC_MAX_TARGET; | ||
1375 | shost->max_lun = phba->cfg_max_luns; | ||
1376 | shost->this_id = -1; | ||
1377 | shost->max_cmd_len = 16; | ||
1372 | /* | 1378 | /* |
1373 | * Bring down the SLI Layer. This step disable all interrupts, | 1379 | * Set initial can_queue value since 0 is no longer supported and |
1374 | * clears the rings, discards all mailbox commands, and resets | 1380 | * scsi_add_host will fail. This will be adjusted later based on the |
1375 | * the HBA. | 1381 | * max xri value determined in hba setup. |
1376 | */ | 1382 | */ |
1377 | lpfc_sli_hba_down(phba); | 1383 | shost->can_queue = phba->cfg_hba_queue_depth - 10; |
1378 | lpfc_sli_brdrestart(phba); | 1384 | shost->transportt = lpfc_transport_template; |
1379 | 1385 | ||
1380 | /* Release the irq reservation */ | 1386 | /* Initialize all internally managed lists. */ |
1381 | free_irq(phba->pcidev->irq, phba); | 1387 | INIT_LIST_HEAD(&vport->fc_nodes); |
1382 | pci_disable_msi(phba->pcidev); | 1388 | spin_lock_init(&vport->work_port_lock); |
1383 | 1389 | ||
1384 | lpfc_cleanup(phba); | 1390 | init_timer(&vport->fc_disctmo); |
1385 | lpfc_stop_timer(phba); | 1391 | vport->fc_disctmo.function = lpfc_disc_timeout; |
1386 | phba->work_hba_events = 0; | 1392 | vport->fc_disctmo.data = (unsigned long) vport; |
1387 | 1393 | ||
1388 | /* | 1394 | init_timer(&vport->fc_fdmitmo); |
1389 | * Call scsi_free before mem_free since scsi bufs are released to their | 1395 | vport->fc_fdmitmo.function = lpfc_fdmi_tmo; |
1390 | * corresponding pools here. | 1396 | vport->fc_fdmitmo.data = (unsigned long) vport; |
1391 | */ | ||
1392 | lpfc_scsi_free(phba); | ||
1393 | lpfc_mem_free(phba); | ||
1394 | 1397 | ||
1395 | /* Free resources associated with SLI2 interface */ | 1398 | init_timer(&vport->els_tmofunc); |
1396 | dma_free_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE, | 1399 | vport->els_tmofunc.function = lpfc_els_timeout; |
1397 | phba->slim2p, phba->slim2p_mapping); | 1400 | vport->els_tmofunc.data = (unsigned long) vport; |
1398 | 1401 | ||
1399 | /* unmap adapter SLIM and Control Registers */ | 1402 | error = scsi_add_host(shost, &phba->pcidev->dev); |
1400 | iounmap(phba->ctrl_regs_memmap_p); | 1403 | if (error) |
1401 | iounmap(phba->slim_memmap_p); | 1404 | goto out_put_shost; |
1402 | 1405 | ||
1403 | pci_release_regions(phba->pcidev); | 1406 | list_add_tail(&vport->listentry, &phba->port_list); |
1404 | pci_disable_device(phba->pcidev); | 1407 | scsi_scan_host(shost); |
1408 | return vport; | ||
1405 | 1409 | ||
1406 | idr_remove(&lpfc_hba_index, phba->brd_no); | 1410 | out_put_shost: |
1407 | scsi_host_put(phba->host); | 1411 | scsi_host_put(shost); |
1412 | out: | ||
1413 | return NULL; | ||
1414 | } | ||
1415 | |||
1416 | void | ||
1417 | destroy_port(struct lpfc_vport *vport) | ||
1418 | { | ||
1419 | lpfc_cleanup(vport); | ||
1420 | list_del(&vport->listentry); | ||
1421 | lpfc_free_sysfs_attr(vport); | ||
1422 | fc_remove_host(lpfc_shost_from_vport(vport)); | ||
1423 | scsi_remove_host(lpfc_shost_from_vport(vport)); | ||
1424 | return; | ||
1408 | } | 1425 | } |
1409 | 1426 | ||
1410 | void lpfc_scan_start(struct Scsi_Host *host) | 1427 | static void |
1428 | lpfc_remove_device(struct lpfc_vport *vport) | ||
1411 | { | 1429 | { |
1412 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 1430 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1431 | struct lpfc_hba *phba = vport->phba; | ||
1413 | 1432 | ||
1414 | if (lpfc_alloc_sysfs_attr(phba)) | 1433 | lpfc_free_sysfs_attr(vport); |
1415 | goto error; | ||
1416 | 1434 | ||
1417 | phba->MBslimaddr = phba->slim_memmap_p; | 1435 | spin_lock_irq(shost->host_lock); |
1418 | phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET; | 1436 | vport->fc_flag |= FC_UNLOADING; |
1419 | phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET; | 1437 | spin_unlock_irq(shost->host_lock); |
1420 | phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; | 1438 | |
1421 | phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; | 1439 | fc_remove_host(shost); |
1440 | scsi_remove_host(shost); | ||
1441 | |||
1442 | kthread_stop(phba->worker_thread); | ||
1443 | } | ||
1444 | |||
1445 | void lpfc_scan_start(struct Scsi_Host *shost) | ||
1446 | { | ||
1447 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
1448 | struct lpfc_hba *phba = vport->phba; | ||
1422 | 1449 | ||
1423 | if (lpfc_sli_hba_setup(phba)) | 1450 | if (lpfc_alloc_sysfs_attr(vport)) |
1424 | goto error; | 1451 | goto error; |
1425 | 1452 | ||
1426 | /* | 1453 | /* |
1427 | * hba setup may have changed the hba_queue_depth so we need to adjust | 1454 | * hba setup may have changed the hba_queue_depth so we need to adjust |
1428 | * the value of can_queue. | 1455 | * the value of can_queue. |
1429 | */ | 1456 | */ |
1430 | host->can_queue = phba->cfg_hba_queue_depth - 10; | 1457 | shost->can_queue = phba->cfg_hba_queue_depth - 10; |
1431 | return; | 1458 | return; |
1432 | 1459 | ||
1433 | error: | 1460 | error: |
1434 | lpfc_remove_device(phba); | 1461 | lpfc_remove_device(vport); |
1435 | } | 1462 | } |
1436 | 1463 | ||
1437 | int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) | 1464 | int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) |
1438 | { | 1465 | { |
1439 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; | 1466 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1467 | struct lpfc_hba *phba = vport->phba; | ||
1440 | 1468 | ||
1441 | if (!phba->host) | 1469 | if (time >= 30 * HZ) { |
1442 | return 1; | 1470 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
1443 | if (time >= 30 * HZ) | 1471 | "%d:0461 Scanning longer than 30 " |
1472 | "seconds. Continuing initialization\n", | ||
1473 | phba->brd_no); | ||
1444 | goto finished; | 1474 | goto finished; |
1475 | } | ||
1476 | if (time >= 15 * HZ && phba->link_state <= LPFC_LINK_DOWN) { | ||
1477 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
1478 | "%d:0465 Link down longer than 15 " | ||
1479 | "seconds. Continuing initialization\n", | ||
1480 | phba->brd_no); | ||
1481 | goto finished; | ||
1482 | } | ||
1445 | 1483 | ||
1446 | if (phba->hba_state != LPFC_HBA_READY) | 1484 | if (vport->port_state != LPFC_VPORT_READY) |
1447 | return 0; | ||
1448 | if (phba->num_disc_nodes || phba->fc_prli_sent) | ||
1449 | return 0; | 1485 | return 0; |
1450 | if ((phba->fc_map_cnt == 0) && (time < 2 * HZ)) | 1486 | if (vport->num_disc_nodes || vport->fc_prli_sent) |
1451 | return 0; | 1487 | return 0; |
1452 | if (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) | 1488 | if (vport->fc_map_cnt == 0 && time < 2 * HZ) |
1453 | return 0; | 1489 | return 0; |
1454 | if ((phba->hba_state > LPFC_LINK_DOWN) || (time < 15 * HZ)) | 1490 | if ((phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) != 0) |
1455 | return 0; | 1491 | return 0; |
1456 | 1492 | ||
1457 | finished: | 1493 | finished: |
1458 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) { | ||
1459 | spin_lock_irq(shost->host_lock); | ||
1460 | lpfc_poll_start_timer(phba); | ||
1461 | spin_unlock_irq(shost->host_lock); | ||
1462 | } | ||
1463 | |||
1464 | /* | 1494 | /* |
1465 | * set fixed host attributes | 1495 | * Set fixed host attributes. Must done after lpfc_sli_hba_setup(). |
1466 | * Must done after lpfc_sli_hba_setup() | ||
1467 | */ | 1496 | */ |
1468 | 1497 | ||
1469 | fc_host_node_name(shost) = wwn_to_u64(phba->fc_nodename.u.wwn); | 1498 | fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn); |
1470 | fc_host_port_name(shost) = wwn_to_u64(phba->fc_portname.u.wwn); | 1499 | fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn); |
1471 | fc_host_supported_classes(shost) = FC_COS_CLASS3; | 1500 | fc_host_supported_classes(shost) = FC_COS_CLASS3; |
1472 | 1501 | ||
1473 | memset(fc_host_supported_fc4s(shost), 0, | 1502 | memset(fc_host_supported_fc4s(shost), 0, |
1474 | sizeof(fc_host_supported_fc4s(shost))); | 1503 | sizeof(fc_host_supported_fc4s(shost))); |
1475 | fc_host_supported_fc4s(shost)[2] = 1; | 1504 | fc_host_supported_fc4s(shost)[2] = 1; |
1476 | fc_host_supported_fc4s(shost)[7] = 1; | 1505 | fc_host_supported_fc4s(shost)[7] = 1; |
1477 | 1506 | ||
@@ -1488,17 +1517,17 @@ finished: | |||
1488 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT; | 1517 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT; |
1489 | 1518 | ||
1490 | fc_host_maxframe_size(shost) = | 1519 | fc_host_maxframe_size(shost) = |
1491 | ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) | | 1520 | (((uint32_t) vport->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) | |
1492 | (uint32_t) phba->fc_sparam.cmn.bbRcvSizeLsb); | 1521 | (uint32_t) vport->fc_sparam.cmn.bbRcvSizeLsb; |
1493 | 1522 | ||
1494 | /* This value is also unchanging */ | 1523 | /* This value is also unchanging */ |
1495 | memset(fc_host_active_fc4s(shost), 0, | 1524 | memset(fc_host_active_fc4s(shost), 0, |
1496 | sizeof(fc_host_active_fc4s(shost))); | 1525 | sizeof(fc_host_active_fc4s(shost))); |
1497 | fc_host_active_fc4s(shost)[2] = 1; | 1526 | fc_host_active_fc4s(shost)[2] = 1; |
1498 | fc_host_active_fc4s(shost)[7] = 1; | 1527 | fc_host_active_fc4s(shost)[7] = 1; |
1499 | 1528 | ||
1500 | spin_lock_irq(shost->host_lock); | 1529 | spin_lock_irq(shost->host_lock); |
1501 | phba->fc_flag &= ~FC_LOADING; | 1530 | vport->fc_flag &= ~FC_LOADING; |
1502 | spin_unlock_irq(shost->host_lock); | 1531 | spin_unlock_irq(shost->host_lock); |
1503 | 1532 | ||
1504 | return 1; | 1533 | return 1; |
@@ -1507,10 +1536,11 @@ finished: | |||
1507 | static int __devinit | 1536 | static int __devinit |
1508 | lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | 1537 | lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) |
1509 | { | 1538 | { |
1510 | struct Scsi_Host *host; | 1539 | struct lpfc_vport *vport = NULL; |
1511 | struct lpfc_hba *phba; | 1540 | struct lpfc_hba *phba; |
1512 | struct lpfc_sli *psli; | 1541 | struct lpfc_sli *psli; |
1513 | struct lpfc_iocbq *iocbq_entry = NULL, *iocbq_next = NULL; | 1542 | struct lpfc_iocbq *iocbq_entry = NULL, *iocbq_next = NULL; |
1543 | struct Scsi_Host *shost = NULL; | ||
1514 | unsigned long bar0map_len, bar2map_len; | 1544 | unsigned long bar0map_len, bar2map_len; |
1515 | int error = -ENODEV, retval; | 1545 | int error = -ENODEV, retval; |
1516 | int i; | 1546 | int i; |
@@ -1521,61 +1551,41 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1521 | if (pci_request_regions(pdev, LPFC_DRIVER_NAME)) | 1551 | if (pci_request_regions(pdev, LPFC_DRIVER_NAME)) |
1522 | goto out_disable_device; | 1552 | goto out_disable_device; |
1523 | 1553 | ||
1524 | host = scsi_host_alloc(&lpfc_template, sizeof (struct lpfc_hba)); | 1554 | phba = kzalloc(sizeof (struct lpfc_hba), GFP_KERNEL); |
1525 | if (!host) | 1555 | if (!phba) |
1526 | goto out_release_regions; | 1556 | goto out_release_regions; |
1527 | 1557 | ||
1528 | phba = (struct lpfc_hba*)host->hostdata; | 1558 | spin_lock_init(&phba->hbalock); |
1529 | memset(phba, 0, sizeof (struct lpfc_hba)); | ||
1530 | phba->host = host; | ||
1531 | 1559 | ||
1532 | phba->fc_flag |= FC_LOADING; | ||
1533 | phba->pcidev = pdev; | 1560 | phba->pcidev = pdev; |
1534 | 1561 | ||
1535 | /* Assign an unused board number */ | 1562 | /* Assign an unused board number */ |
1536 | if (!idr_pre_get(&lpfc_hba_index, GFP_KERNEL)) | 1563 | if (!idr_pre_get(&lpfc_hba_index, GFP_KERNEL)) |
1537 | goto out_put_host; | 1564 | goto out_free_phba; |
1538 | 1565 | ||
1539 | error = idr_get_new(&lpfc_hba_index, NULL, &phba->brd_no); | 1566 | error = idr_get_new(&lpfc_hba_index, NULL, &phba->brd_no); |
1540 | if (error) | 1567 | if (error) |
1541 | goto out_put_host; | 1568 | goto out_free_phba; |
1569 | |||
1570 | INIT_LIST_HEAD(&phba->port_list); | ||
1542 | 1571 | ||
1543 | host->unique_id = phba->brd_no; | 1572 | /* |
1573 | * Get all the module params for configuring this host and then | ||
1574 | * establish the host. | ||
1575 | */ | ||
1576 | lpfc_get_cfgparam(phba); | ||
1544 | 1577 | ||
1545 | /* Initialize timers used by driver */ | 1578 | /* Initialize timers used by driver */ |
1546 | init_timer(&phba->fc_estabtmo); | 1579 | init_timer(&phba->fc_estabtmo); |
1547 | phba->fc_estabtmo.function = lpfc_establish_link_tmo; | 1580 | phba->fc_estabtmo.function = lpfc_establish_link_tmo; |
1548 | phba->fc_estabtmo.data = (unsigned long)phba; | 1581 | phba->fc_estabtmo.data = (unsigned long) phba; |
1549 | init_timer(&phba->fc_disctmo); | ||
1550 | phba->fc_disctmo.function = lpfc_disc_timeout; | ||
1551 | phba->fc_disctmo.data = (unsigned long)phba; | ||
1552 | |||
1553 | init_timer(&phba->fc_fdmitmo); | ||
1554 | phba->fc_fdmitmo.function = lpfc_fdmi_tmo; | ||
1555 | phba->fc_fdmitmo.data = (unsigned long)phba; | ||
1556 | init_timer(&phba->els_tmofunc); | ||
1557 | phba->els_tmofunc.function = lpfc_els_timeout; | ||
1558 | phba->els_tmofunc.data = (unsigned long)phba; | ||
1559 | psli = &phba->sli; | 1582 | psli = &phba->sli; |
1560 | init_timer(&psli->mbox_tmo); | 1583 | init_timer(&psli->mbox_tmo); |
1561 | psli->mbox_tmo.function = lpfc_mbox_timeout; | 1584 | psli->mbox_tmo.function = lpfc_mbox_timeout; |
1562 | psli->mbox_tmo.data = (unsigned long)phba; | 1585 | psli->mbox_tmo.data = (unsigned long) phba; |
1563 | |||
1564 | init_timer(&phba->fcp_poll_timer); | 1586 | init_timer(&phba->fcp_poll_timer); |
1565 | phba->fcp_poll_timer.function = lpfc_poll_timeout; | 1587 | phba->fcp_poll_timer.function = lpfc_poll_timeout; |
1566 | phba->fcp_poll_timer.data = (unsigned long)phba; | 1588 | phba->fcp_poll_timer.data = (unsigned long) phba; |
1567 | |||
1568 | /* | ||
1569 | * Get all the module params for configuring this host and then | ||
1570 | * establish the host parameters. | ||
1571 | */ | ||
1572 | lpfc_get_cfgparam(phba); | ||
1573 | |||
1574 | host->max_id = LPFC_MAX_TARGET; | ||
1575 | host->max_lun = phba->cfg_max_luns; | ||
1576 | host->this_id = -1; | ||
1577 | |||
1578 | INIT_LIST_HEAD(&phba->fc_nodes); | ||
1579 | 1589 | ||
1580 | pci_set_master(pdev); | 1590 | pci_set_master(pdev); |
1581 | retval = pci_set_mwi(pdev); | 1591 | retval = pci_set_mwi(pdev); |
@@ -1653,10 +1663,11 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1653 | error = -ENOMEM; | 1663 | error = -ENOMEM; |
1654 | goto out_free_iocbq; | 1664 | goto out_free_iocbq; |
1655 | } | 1665 | } |
1656 | spin_lock_irq(phba->host->host_lock); | 1666 | |
1667 | spin_lock_irq(&phba->hbalock); | ||
1657 | list_add(&iocbq_entry->list, &phba->lpfc_iocb_list); | 1668 | list_add(&iocbq_entry->list, &phba->lpfc_iocb_list); |
1658 | phba->total_iocbq_bufs++; | 1669 | phba->total_iocbq_bufs++; |
1659 | spin_unlock_irq(phba->host->host_lock); | 1670 | spin_unlock_irq(&phba->hbalock); |
1660 | } | 1671 | } |
1661 | 1672 | ||
1662 | /* Initialize HBA structure */ | 1673 | /* Initialize HBA structure */ |
@@ -1677,22 +1688,19 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1677 | goto out_free_iocbq; | 1688 | goto out_free_iocbq; |
1678 | } | 1689 | } |
1679 | 1690 | ||
1680 | /* | ||
1681 | * Set initial can_queue value since 0 is no longer supported and | ||
1682 | * scsi_add_host will fail. This will be adjusted later based on the | ||
1683 | * max xri value determined in hba setup. | ||
1684 | */ | ||
1685 | host->can_queue = phba->cfg_hba_queue_depth - 10; | ||
1686 | |||
1687 | /* Tell the midlayer we support 16 byte commands */ | ||
1688 | host->max_cmd_len = 16; | ||
1689 | |||
1690 | /* Initialize the list of scsi buffers used by driver for scsi IO. */ | 1691 | /* Initialize the list of scsi buffers used by driver for scsi IO. */ |
1691 | spin_lock_init(&phba->scsi_buf_list_lock); | 1692 | spin_lock_init(&phba->scsi_buf_list_lock); |
1692 | INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list); | 1693 | INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list); |
1693 | 1694 | ||
1694 | host->transportt = lpfc_transport_template; | 1695 | vport = lpfc_create_port(phba, phba->brd_no); |
1695 | pci_set_drvdata(pdev, host); | 1696 | if (!vport) |
1697 | goto out_kthread_stop; | ||
1698 | |||
1699 | shost = lpfc_shost_from_vport(vport); | ||
1700 | vport->port_type = LPFC_PHYSICAL_PORT; | ||
1701 | phba->pport = vport; | ||
1702 | |||
1703 | pci_set_drvdata(pdev, lpfc_shost_from_vport(vport)); | ||
1696 | 1704 | ||
1697 | if (phba->cfg_use_msi) { | 1705 | if (phba->cfg_use_msi) { |
1698 | error = pci_enable_msi(phba->pcidev); | 1706 | error = pci_enable_msi(phba->pcidev); |
@@ -1703,36 +1711,46 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1703 | } | 1711 | } |
1704 | 1712 | ||
1705 | error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, | 1713 | error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, |
1706 | LPFC_DRIVER_NAME, phba); | 1714 | LPFC_DRIVER_NAME, phba); |
1707 | if (error) { | 1715 | if (error) { |
1708 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1716 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1709 | "%d:0451 Enable interrupt handler failed\n", | 1717 | "%d:0451 Enable interrupt handler failed\n", |
1710 | phba->brd_no); | 1718 | phba->brd_no); |
1711 | goto out_kthread_stop; | 1719 | goto out_destroy_port; |
1712 | } | 1720 | } |
1713 | 1721 | ||
1714 | error = scsi_add_host(host, &pdev->dev); | 1722 | phba->MBslimaddr = phba->slim_memmap_p; |
1723 | phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET; | ||
1724 | phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET; | ||
1725 | phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; | ||
1726 | phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; | ||
1727 | |||
1728 | error = lpfc_sli_hba_setup(phba); | ||
1715 | if (error) | 1729 | if (error) |
1716 | goto out_free_irq; | 1730 | goto out_free_irq; |
1717 | 1731 | ||
1718 | scsi_scan_host(host); | 1732 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) { |
1733 | spin_lock_irq(shost->host_lock); | ||
1734 | lpfc_poll_start_timer(phba); | ||
1735 | spin_unlock_irq(shost->host_lock); | ||
1736 | } | ||
1719 | 1737 | ||
1720 | return 0; | 1738 | return 0; |
1721 | 1739 | ||
1722 | out_free_irq: | 1740 | out_free_irq: |
1723 | lpfc_stop_timer(phba); | 1741 | lpfc_stop_timer(phba); |
1724 | phba->work_hba_events = 0; | 1742 | phba->pport->work_port_events = 0; |
1725 | free_irq(phba->pcidev->irq, phba); | 1743 | free_irq(phba->pcidev->irq, phba); |
1726 | pci_disable_msi(phba->pcidev); | 1744 | pci_disable_msi(phba->pcidev); |
1745 | out_destroy_port: | ||
1746 | destroy_port(vport); | ||
1727 | out_kthread_stop: | 1747 | out_kthread_stop: |
1728 | kthread_stop(phba->worker_thread); | 1748 | kthread_stop(phba->worker_thread); |
1729 | out_free_iocbq: | 1749 | out_free_iocbq: |
1730 | list_for_each_entry_safe(iocbq_entry, iocbq_next, | 1750 | list_for_each_entry_safe(iocbq_entry, iocbq_next, |
1731 | &phba->lpfc_iocb_list, list) { | 1751 | &phba->lpfc_iocb_list, list) { |
1732 | spin_lock_irq(phba->host->host_lock); | ||
1733 | kfree(iocbq_entry); | 1752 | kfree(iocbq_entry); |
1734 | phba->total_iocbq_bufs--; | 1753 | phba->total_iocbq_bufs--; |
1735 | spin_unlock_irq(phba->host->host_lock); | ||
1736 | } | 1754 | } |
1737 | lpfc_mem_free(phba); | 1755 | lpfc_mem_free(phba); |
1738 | out_free_slim: | 1756 | out_free_slim: |
@@ -1744,9 +1762,8 @@ out_iounmap_slim: | |||
1744 | iounmap(phba->slim_memmap_p); | 1762 | iounmap(phba->slim_memmap_p); |
1745 | out_idr_remove: | 1763 | out_idr_remove: |
1746 | idr_remove(&lpfc_hba_index, phba->brd_no); | 1764 | idr_remove(&lpfc_hba_index, phba->brd_no); |
1747 | out_put_host: | 1765 | out_free_phba: |
1748 | phba->host = NULL; | 1766 | kfree(phba); |
1749 | scsi_host_put(host); | ||
1750 | out_release_regions: | 1767 | out_release_regions: |
1751 | pci_release_regions(pdev); | 1768 | pci_release_regions(pdev); |
1752 | out_disable_device: | 1769 | out_disable_device: |
@@ -1759,12 +1776,55 @@ out: | |||
1759 | static void __devexit | 1776 | static void __devexit |
1760 | lpfc_pci_remove_one(struct pci_dev *pdev) | 1777 | lpfc_pci_remove_one(struct pci_dev *pdev) |
1761 | { | 1778 | { |
1762 | struct Scsi_Host *host = pci_get_drvdata(pdev); | 1779 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
1763 | struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata; | 1780 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1781 | struct lpfc_hba *phba = vport->phba; | ||
1782 | |||
1783 | vport->load_flag |= FC_UNLOADING; | ||
1784 | lpfc_remove_device(vport); | ||
1785 | |||
1786 | /* | ||
1787 | * Bring down the SLI Layer. This step disable all interrupts, | ||
1788 | * clears the rings, discards all mailbox commands, and resets | ||
1789 | * the HBA. | ||
1790 | */ | ||
1791 | lpfc_sli_hba_down(phba); | ||
1792 | lpfc_sli_brdrestart(phba); | ||
1793 | |||
1794 | lpfc_stop_timer(phba); | ||
1795 | |||
1796 | kthread_stop(phba->worker_thread); | ||
1797 | |||
1798 | /* Release the irq reservation */ | ||
1799 | free_irq(phba->pcidev->irq, phba); | ||
1800 | pci_disable_msi(phba->pcidev); | ||
1764 | 1801 | ||
1765 | lpfc_remove_device(phba); | 1802 | vport->work_port_events = 0; |
1803 | destroy_port(vport); | ||
1766 | 1804 | ||
1767 | pci_set_drvdata(pdev, NULL); | 1805 | pci_set_drvdata(pdev, NULL); |
1806 | |||
1807 | /* | ||
1808 | * Call scsi_free before mem_free since scsi bufs are released to their | ||
1809 | * corresponding pools here. | ||
1810 | */ | ||
1811 | lpfc_scsi_free(phba); | ||
1812 | lpfc_mem_free(phba); | ||
1813 | |||
1814 | /* Free resources associated with SLI2 interface */ | ||
1815 | dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE, | ||
1816 | phba->slim2p, phba->slim2p_mapping); | ||
1817 | |||
1818 | /* unmap adapter SLIM and Control Registers */ | ||
1819 | iounmap(phba->ctrl_regs_memmap_p); | ||
1820 | iounmap(phba->slim_memmap_p); | ||
1821 | |||
1822 | idr_remove(&lpfc_hba_index, phba->brd_no); | ||
1823 | |||
1824 | kfree(phba); | ||
1825 | |||
1826 | pci_release_regions(pdev); | ||
1827 | pci_disable_device(pdev); | ||
1768 | } | 1828 | } |
1769 | 1829 | ||
1770 | /** | 1830 | /** |
@@ -1822,10 +1882,12 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |||
1822 | pci_set_master(pdev); | 1882 | pci_set_master(pdev); |
1823 | 1883 | ||
1824 | /* Re-establishing Link */ | 1884 | /* Re-establishing Link */ |
1825 | spin_lock_irq(phba->host->host_lock); | 1885 | spin_lock_irq(&phba->hbalock); |
1826 | phba->fc_flag |= FC_ESTABLISH_LINK; | 1886 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; |
1887 | spin_unlock_irq(&phba->hbalock); | ||
1888 | spin_lock_irq(host->host_lock); | ||
1827 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 1889 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
1828 | spin_unlock_irq(phba->host->host_lock); | 1890 | spin_unlock_irq(host->host_lock); |
1829 | 1891 | ||
1830 | 1892 | ||
1831 | /* Take device offline; this will perform cleanup */ | 1893 | /* Take device offline; this will perform cleanup */ |
@@ -1935,7 +1997,7 @@ static struct pci_driver lpfc_driver = { | |||
1935 | .id_table = lpfc_id_table, | 1997 | .id_table = lpfc_id_table, |
1936 | .probe = lpfc_pci_probe_one, | 1998 | .probe = lpfc_pci_probe_one, |
1937 | .remove = __devexit_p(lpfc_pci_remove_one), | 1999 | .remove = __devexit_p(lpfc_pci_remove_one), |
1938 | .err_handler = &lpfc_err_handler, | 2000 | .err_handler = &lpfc_err_handler, |
1939 | }; | 2001 | }; |
1940 | 2002 | ||
1941 | static int __init | 2003 | static int __init |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 8041c3f06f7..86757ec5305 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -106,7 +106,7 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp) | |||
106 | */ | 106 | */ |
107 | pmb->context1 = (uint8_t *) mp; | 107 | pmb->context1 = (uint8_t *) mp; |
108 | mb->mbxOwner = OWN_HOST; | 108 | mb->mbxOwner = OWN_HOST; |
109 | return (0); | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | /**********************************************/ | 112 | /**********************************************/ |
@@ -134,6 +134,7 @@ lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
134 | void | 134 | void |
135 | lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 135 | lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) |
136 | { | 136 | { |
137 | struct lpfc_vport *vport = phba->pport; | ||
137 | MAILBOX_t *mb = &pmb->mb; | 138 | MAILBOX_t *mb = &pmb->mb; |
138 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 139 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
139 | 140 | ||
@@ -147,7 +148,7 @@ lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
147 | mb->un.varCfgLnk.cr_count = phba->cfg_cr_count; | 148 | mb->un.varCfgLnk.cr_count = phba->cfg_cr_count; |
148 | } | 149 | } |
149 | 150 | ||
150 | mb->un.varCfgLnk.myId = phba->fc_myDID; | 151 | mb->un.varCfgLnk.myId = vport->fc_myDID; |
151 | mb->un.varCfgLnk.edtov = phba->fc_edtov; | 152 | mb->un.varCfgLnk.edtov = phba->fc_edtov; |
152 | mb->un.varCfgLnk.arbtov = phba->fc_arbtov; | 153 | mb->un.varCfgLnk.arbtov = phba->fc_arbtov; |
153 | mb->un.varCfgLnk.ratov = phba->fc_ratov; | 154 | mb->un.varCfgLnk.ratov = phba->fc_ratov; |
@@ -208,7 +209,7 @@ lpfc_init_link(struct lpfc_hba * phba, | |||
208 | */ | 209 | */ |
209 | vpd = &phba->vpd; | 210 | vpd = &phba->vpd; |
210 | if (vpd->rev.feaLevelHigh >= 0x02){ | 211 | if (vpd->rev.feaLevelHigh >= 0x02){ |
211 | switch(linkspeed){ | 212 | switch (linkspeed){ |
212 | case LINK_SPEED_1G: | 213 | case LINK_SPEED_1G: |
213 | case LINK_SPEED_2G: | 214 | case LINK_SPEED_2G: |
214 | case LINK_SPEED_4G: | 215 | case LINK_SPEED_4G: |
@@ -263,7 +264,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
263 | LOG_MBOX, | 264 | LOG_MBOX, |
264 | "%d:0301 READ_SPARAM: no buffers\n", | 265 | "%d:0301 READ_SPARAM: no buffers\n", |
265 | phba->brd_no); | 266 | phba->brd_no); |
266 | return (1); | 267 | return 1; |
267 | } | 268 | } |
268 | INIT_LIST_HEAD(&mp->list); | 269 | INIT_LIST_HEAD(&mp->list); |
269 | mb->mbxCommand = MBX_READ_SPARM64; | 270 | mb->mbxCommand = MBX_READ_SPARM64; |
@@ -274,7 +275,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
274 | /* save address for completion */ | 275 | /* save address for completion */ |
275 | pmb->context1 = mp; | 276 | pmb->context1 = mp; |
276 | 277 | ||
277 | return (0); | 278 | return 0; |
278 | } | 279 | } |
279 | 280 | ||
280 | /********************************************/ | 281 | /********************************************/ |
@@ -282,7 +283,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
282 | /* mailbox command */ | 283 | /* mailbox command */ |
283 | /********************************************/ | 284 | /********************************************/ |
284 | void | 285 | void |
285 | lpfc_unreg_did(struct lpfc_hba * phba, uint32_t did, LPFC_MBOXQ_t * pmb) | 286 | lpfc_unreg_did(struct lpfc_hba *phba, uint32_t did, LPFC_MBOXQ_t *pmb) |
286 | { | 287 | { |
287 | MAILBOX_t *mb; | 288 | MAILBOX_t *mb; |
288 | 289 | ||
@@ -335,16 +336,13 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
335 | /* mailbox command */ | 336 | /* mailbox command */ |
336 | /********************************************/ | 337 | /********************************************/ |
337 | int | 338 | int |
338 | lpfc_reg_login(struct lpfc_hba * phba, | 339 | lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, |
339 | uint32_t did, uint8_t * param, LPFC_MBOXQ_t * pmb, uint32_t flag) | 340 | LPFC_MBOXQ_t *pmb, uint32_t flag) |
340 | { | 341 | { |
342 | MAILBOX_t *mb = &pmb->mb; | ||
341 | uint8_t *sparam; | 343 | uint8_t *sparam; |
342 | struct lpfc_dmabuf *mp; | 344 | struct lpfc_dmabuf *mp; |
343 | MAILBOX_t *mb; | ||
344 | struct lpfc_sli *psli; | ||
345 | 345 | ||
346 | psli = &phba->sli; | ||
347 | mb = &pmb->mb; | ||
348 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 346 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
349 | 347 | ||
350 | mb->un.varRegLogin.rpi = 0; | 348 | mb->un.varRegLogin.rpi = 0; |
@@ -365,7 +363,7 @@ lpfc_reg_login(struct lpfc_hba * phba, | |||
365 | "%d:0302 REG_LOGIN: no buffers Data x%x x%x\n", | 363 | "%d:0302 REG_LOGIN: no buffers Data x%x x%x\n", |
366 | phba->brd_no, | 364 | phba->brd_no, |
367 | (uint32_t) did, (uint32_t) flag); | 365 | (uint32_t) did, (uint32_t) flag); |
368 | return (1); | 366 | return 1; |
369 | } | 367 | } |
370 | INIT_LIST_HEAD(&mp->list); | 368 | INIT_LIST_HEAD(&mp->list); |
371 | sparam = mp->virt; | 369 | sparam = mp->virt; |
@@ -381,7 +379,7 @@ lpfc_reg_login(struct lpfc_hba * phba, | |||
381 | mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys); | 379 | mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys); |
382 | mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys); | 380 | mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys); |
383 | 381 | ||
384 | return (0); | 382 | return 0; |
385 | } | 383 | } |
386 | 384 | ||
387 | /**********************************************/ | 385 | /**********************************************/ |
@@ -389,7 +387,7 @@ lpfc_reg_login(struct lpfc_hba * phba, | |||
389 | /* mailbox command */ | 387 | /* mailbox command */ |
390 | /**********************************************/ | 388 | /**********************************************/ |
391 | void | 389 | void |
392 | lpfc_unreg_login(struct lpfc_hba * phba, uint32_t rpi, LPFC_MBOXQ_t * pmb) | 390 | lpfc_unreg_login(struct lpfc_hba *phba, uint32_t rpi, LPFC_MBOXQ_t * pmb) |
393 | { | 391 | { |
394 | MAILBOX_t *mb; | 392 | MAILBOX_t *mb; |
395 | 393 | ||
@@ -412,14 +410,14 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba) | |||
412 | PCB_t *pcbp = &phba->slim2p->pcb; | 410 | PCB_t *pcbp = &phba->slim2p->pcb; |
413 | dma_addr_t pdma_addr; | 411 | dma_addr_t pdma_addr; |
414 | uint32_t offset; | 412 | uint32_t offset; |
415 | uint32_t iocbCnt; | 413 | uint32_t iocbCnt = 0; |
416 | int i; | 414 | int i; |
417 | 415 | ||
418 | pcbp->maxRing = (psli->num_rings - 1); | 416 | pcbp->maxRing = (psli->num_rings - 1); |
419 | 417 | ||
420 | iocbCnt = 0; | ||
421 | for (i = 0; i < psli->num_rings; i++) { | 418 | for (i = 0; i < psli->num_rings; i++) { |
422 | pring = &psli->ring[i]; | 419 | pring = &psli->ring[i]; |
420 | |||
423 | /* A ring MUST have both cmd and rsp entries defined to be | 421 | /* A ring MUST have both cmd and rsp entries defined to be |
424 | valid */ | 422 | valid */ |
425 | if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) { | 423 | if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) { |
@@ -462,9 +460,7 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba) | |||
462 | void | 460 | void |
463 | lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 461 | lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) |
464 | { | 462 | { |
465 | MAILBOX_t *mb; | 463 | MAILBOX_t *mb = &pmb->mb; |
466 | |||
467 | mb = &pmb->mb; | ||
468 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 464 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
469 | mb->un.varRdRev.cv = 1; | 465 | mb->un.varRdRev.cv = 1; |
470 | mb->mbxCommand = MBX_READ_REV; | 466 | mb->mbxCommand = MBX_READ_REV; |
@@ -644,8 +640,7 @@ lpfc_mbox_get(struct lpfc_hba * phba) | |||
644 | LPFC_MBOXQ_t *mbq = NULL; | 640 | LPFC_MBOXQ_t *mbq = NULL; |
645 | struct lpfc_sli *psli = &phba->sli; | 641 | struct lpfc_sli *psli = &phba->sli; |
646 | 642 | ||
647 | list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, | 643 | list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list); |
648 | list); | ||
649 | if (mbq) { | 644 | if (mbq) { |
650 | psli->mboxq_cnt--; | 645 | psli->mboxq_cnt--; |
651 | } | 646 | } |
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index ec3bbbde6f7..3aa1dff1544 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -38,6 +38,8 @@ | |||
38 | #define LPFC_MBUF_POOL_SIZE 64 /* max elements in MBUF safety pool */ | 38 | #define LPFC_MBUF_POOL_SIZE 64 /* max elements in MBUF safety pool */ |
39 | #define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */ | 39 | #define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */ |
40 | 40 | ||
41 | |||
42 | |||
41 | int | 43 | int |
42 | lpfc_mem_alloc(struct lpfc_hba * phba) | 44 | lpfc_mem_alloc(struct lpfc_hba * phba) |
43 | { | 45 | { |
@@ -84,6 +86,7 @@ lpfc_mem_alloc(struct lpfc_hba * phba) | |||
84 | 86 | ||
85 | fail_free_mbox_pool: | 87 | fail_free_mbox_pool: |
86 | mempool_destroy(phba->mbox_mem_pool); | 88 | mempool_destroy(phba->mbox_mem_pool); |
89 | phba->mbox_mem_pool = NULL; | ||
87 | fail_free_mbuf_pool: | 90 | fail_free_mbuf_pool: |
88 | while (i--) | 91 | while (i--) |
89 | pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, | 92 | pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, |
@@ -91,8 +94,10 @@ lpfc_mem_alloc(struct lpfc_hba * phba) | |||
91 | kfree(pool->elements); | 94 | kfree(pool->elements); |
92 | fail_free_lpfc_mbuf_pool: | 95 | fail_free_lpfc_mbuf_pool: |
93 | pci_pool_destroy(phba->lpfc_mbuf_pool); | 96 | pci_pool_destroy(phba->lpfc_mbuf_pool); |
97 | phba->lpfc_mbuf_pool = NULL; | ||
94 | fail_free_dma_buf_pool: | 98 | fail_free_dma_buf_pool: |
95 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); | 99 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); |
100 | phba->lpfc_scsi_dma_buf_pool = NULL; | ||
96 | fail: | 101 | fail: |
97 | return -ENOMEM; | 102 | return -ENOMEM; |
98 | } | 103 | } |
@@ -106,6 +111,7 @@ lpfc_mem_free(struct lpfc_hba * phba) | |||
106 | struct lpfc_dmabuf *mp; | 111 | struct lpfc_dmabuf *mp; |
107 | int i; | 112 | int i; |
108 | 113 | ||
114 | spin_lock_irq(&phba->hbalock); | ||
109 | list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) { | 115 | list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) { |
110 | mp = (struct lpfc_dmabuf *) (mbox->context1); | 116 | mp = (struct lpfc_dmabuf *) (mbox->context1); |
111 | if (mp) { | 117 | if (mp) { |
@@ -117,6 +123,7 @@ lpfc_mem_free(struct lpfc_hba * phba) | |||
117 | } | 123 | } |
118 | 124 | ||
119 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 125 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
126 | spin_unlock_irq(&phba->hbalock); | ||
120 | if (psli->mbox_active) { | 127 | if (psli->mbox_active) { |
121 | mbox = psli->mbox_active; | 128 | mbox = psli->mbox_active; |
122 | mp = (struct lpfc_dmabuf *) (mbox->context1); | 129 | mp = (struct lpfc_dmabuf *) (mbox->context1); |
@@ -132,12 +139,18 @@ lpfc_mem_free(struct lpfc_hba * phba) | |||
132 | pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, | 139 | pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, |
133 | pool->elements[i].phys); | 140 | pool->elements[i].phys); |
134 | kfree(pool->elements); | 141 | kfree(pool->elements); |
142 | |||
135 | mempool_destroy(phba->nlp_mem_pool); | 143 | mempool_destroy(phba->nlp_mem_pool); |
136 | mempool_destroy(phba->mbox_mem_pool); | 144 | mempool_destroy(phba->mbox_mem_pool); |
137 | 145 | ||
138 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); | 146 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); |
139 | pci_pool_destroy(phba->lpfc_mbuf_pool); | 147 | pci_pool_destroy(phba->lpfc_mbuf_pool); |
140 | 148 | ||
149 | phba->nlp_mem_pool = NULL; | ||
150 | phba->mbox_mem_pool = NULL; | ||
151 | phba->lpfc_scsi_dma_buf_pool = NULL; | ||
152 | phba->lpfc_mbuf_pool = NULL; | ||
153 | |||
141 | /* Free the iocb lookup array */ | 154 | /* Free the iocb lookup array */ |
142 | kfree(psli->iocbq_lookup); | 155 | kfree(psli->iocbq_lookup); |
143 | psli->iocbq_lookup = NULL; | 156 | psli->iocbq_lookup = NULL; |
@@ -148,20 +161,23 @@ void * | |||
148 | lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) | 161 | lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) |
149 | { | 162 | { |
150 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; | 163 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; |
164 | unsigned long iflags; | ||
151 | void *ret; | 165 | void *ret; |
152 | 166 | ||
153 | ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle); | 167 | ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle); |
154 | 168 | ||
169 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
155 | if (!ret && ( mem_flags & MEM_PRI) && pool->current_count) { | 170 | if (!ret && ( mem_flags & MEM_PRI) && pool->current_count) { |
156 | pool->current_count--; | 171 | pool->current_count--; |
157 | ret = pool->elements[pool->current_count].virt; | 172 | ret = pool->elements[pool->current_count].virt; |
158 | *handle = pool->elements[pool->current_count].phys; | 173 | *handle = pool->elements[pool->current_count].phys; |
159 | } | 174 | } |
175 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
160 | return ret; | 176 | return ret; |
161 | } | 177 | } |
162 | 178 | ||
163 | void | 179 | void |
164 | lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) | 180 | __lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) |
165 | { | 181 | { |
166 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; | 182 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; |
167 | 183 | ||
@@ -174,3 +190,14 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) | |||
174 | } | 190 | } |
175 | return; | 191 | return; |
176 | } | 192 | } |
193 | |||
194 | void | ||
195 | lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) | ||
196 | { | ||
197 | unsigned long iflags; | ||
198 | |||
199 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
200 | __lpfc_mbuf_free(phba, virt, dma); | ||
201 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
202 | return; | ||
203 | } | ||
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index b309841e384..e6452b88d95 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -39,16 +39,16 @@ | |||
39 | 39 | ||
40 | /* Called to verify a rcv'ed ADISC was intended for us. */ | 40 | /* Called to verify a rcv'ed ADISC was intended for us. */ |
41 | static int | 41 | static int |
42 | lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | 42 | lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
43 | struct lpfc_name * nn, struct lpfc_name * pn) | 43 | struct lpfc_name *nn, struct lpfc_name *pn) |
44 | { | 44 | { |
45 | /* Compare the ADISC rsp WWNN / WWPN matches our internal node | 45 | /* Compare the ADISC rsp WWNN / WWPN matches our internal node |
46 | * table entry for that node. | 46 | * table entry for that node. |
47 | */ | 47 | */ |
48 | if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0) | 48 | if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name))) |
49 | return 0; | 49 | return 0; |
50 | 50 | ||
51 | if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0) | 51 | if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name))) |
52 | return 0; | 52 | return 0; |
53 | 53 | ||
54 | /* we match, return success */ | 54 | /* we match, return success */ |
@@ -56,11 +56,10 @@ lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
56 | } | 56 | } |
57 | 57 | ||
58 | int | 58 | int |
59 | lpfc_check_sparm(struct lpfc_hba * phba, | 59 | lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
60 | struct lpfc_nodelist * ndlp, struct serv_parm * sp, | 60 | struct serv_parm * sp, uint32_t class) |
61 | uint32_t class) | ||
62 | { | 61 | { |
63 | volatile struct serv_parm *hsp = &phba->fc_sparam; | 62 | volatile struct serv_parm *hsp = &vport->fc_sparam; |
64 | uint16_t hsp_value, ssp_value = 0; | 63 | uint16_t hsp_value, ssp_value = 0; |
65 | 64 | ||
66 | /* | 65 | /* |
@@ -128,8 +127,7 @@ lpfc_check_sparm(struct lpfc_hba * phba, | |||
128 | } | 127 | } |
129 | 128 | ||
130 | static void * | 129 | static void * |
131 | lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, | 130 | lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
132 | struct lpfc_iocbq *cmdiocb, | ||
133 | struct lpfc_iocbq *rspiocb) | 131 | struct lpfc_iocbq *rspiocb) |
134 | { | 132 | { |
135 | struct lpfc_dmabuf *pcmd, *prsp; | 133 | struct lpfc_dmabuf *pcmd, *prsp; |
@@ -168,11 +166,11 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, | |||
168 | * routine effectively results in a "software abort". | 166 | * routine effectively results in a "software abort". |
169 | */ | 167 | */ |
170 | int | 168 | int |
171 | lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 169 | lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) |
172 | { | 170 | { |
173 | LIST_HEAD(completions); | 171 | LIST_HEAD(completions); |
174 | struct lpfc_sli *psli; | 172 | struct lpfc_sli *psli = &phba->sli; |
175 | struct lpfc_sli_ring *pring; | 173 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; |
176 | struct lpfc_iocbq *iocb, *next_iocb; | 174 | struct lpfc_iocbq *iocb, *next_iocb; |
177 | IOCB_t *cmd; | 175 | IOCB_t *cmd; |
178 | 176 | ||
@@ -183,11 +181,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
183 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, | 181 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, |
184 | ndlp->nlp_state, ndlp->nlp_rpi); | 182 | ndlp->nlp_state, ndlp->nlp_rpi); |
185 | 183 | ||
186 | psli = &phba->sli; | ||
187 | pring = &psli->ring[LPFC_ELS_RING]; | ||
188 | |||
189 | /* First check the txq */ | 184 | /* First check the txq */ |
190 | spin_lock_irq(phba->host->host_lock); | 185 | spin_lock_irq(&phba->hbalock); |
191 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { | 186 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { |
192 | /* Check to see if iocb matches the nport we are looking | 187 | /* Check to see if iocb matches the nport we are looking |
193 | for */ | 188 | for */ |
@@ -206,32 +201,34 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
206 | if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) | 201 | if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) |
207 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); | 202 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
208 | } | 203 | } |
209 | spin_unlock_irq(phba->host->host_lock); | 204 | spin_unlock_irq(&phba->hbalock); |
210 | 205 | ||
211 | while (!list_empty(&completions)) { | 206 | while (!list_empty(&completions)) { |
212 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | 207 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); |
213 | cmd = &iocb->iocb; | 208 | cmd = &iocb->iocb; |
214 | list_del(&iocb->list); | 209 | list_del(&iocb->list); |
215 | 210 | ||
216 | if (iocb->iocb_cmpl) { | 211 | if (!iocb->iocb_cmpl) |
212 | lpfc_sli_release_iocbq(phba, iocb); | ||
213 | else { | ||
217 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 214 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
218 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | 215 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
219 | (iocb->iocb_cmpl) (phba, iocb, iocb); | 216 | (iocb->iocb_cmpl) (phba, iocb, iocb); |
220 | } else | 217 | } |
221 | lpfc_sli_release_iocbq(phba, iocb); | ||
222 | } | 218 | } |
223 | 219 | ||
224 | /* If we are delaying issuing an ELS command, cancel it */ | 220 | /* If we are delaying issuing an ELS command, cancel it */ |
225 | if (ndlp->nlp_flag & NLP_DELAY_TMO) | 221 | if (ndlp->nlp_flag & NLP_DELAY_TMO) |
226 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 222 | lpfc_cancel_retry_delay_tmo(phba->pport, ndlp); |
227 | return 0; | 223 | return 0; |
228 | } | 224 | } |
229 | 225 | ||
230 | static int | 226 | static int |
231 | lpfc_rcv_plogi(struct lpfc_hba * phba, | 227 | lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
232 | struct lpfc_nodelist * ndlp, | ||
233 | struct lpfc_iocbq *cmdiocb) | 228 | struct lpfc_iocbq *cmdiocb) |
234 | { | 229 | { |
230 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
231 | struct lpfc_hba *phba = vport->phba; | ||
235 | struct lpfc_dmabuf *pcmd; | 232 | struct lpfc_dmabuf *pcmd; |
236 | uint32_t *lp; | 233 | uint32_t *lp; |
237 | IOCB_t *icmd; | 234 | IOCB_t *icmd; |
@@ -241,14 +238,14 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
241 | int rc; | 238 | int rc; |
242 | 239 | ||
243 | memset(&stat, 0, sizeof (struct ls_rjt)); | 240 | memset(&stat, 0, sizeof (struct ls_rjt)); |
244 | if (phba->hba_state <= LPFC_FLOGI) { | 241 | if (vport->port_state <= LPFC_FLOGI) { |
245 | /* Before responding to PLOGI, check for pt2pt mode. | 242 | /* Before responding to PLOGI, check for pt2pt mode. |
246 | * If we are pt2pt, with an outstanding FLOGI, abort | 243 | * If we are pt2pt, with an outstanding FLOGI, abort |
247 | * the FLOGI and resend it first. | 244 | * the FLOGI and resend it first. |
248 | */ | 245 | */ |
249 | if (phba->fc_flag & FC_PT2PT) { | 246 | if (vport->fc_flag & FC_PT2PT) { |
250 | lpfc_els_abort_flogi(phba); | 247 | lpfc_els_abort_flogi(phba); |
251 | if (!(phba->fc_flag & FC_PT2PT_PLOGI)) { | 248 | if (!(vport->fc_flag & FC_PT2PT_PLOGI)) { |
252 | /* If the other side is supposed to initiate | 249 | /* If the other side is supposed to initiate |
253 | * the PLOGI anyway, just ACC it now and | 250 | * the PLOGI anyway, just ACC it now and |
254 | * move on with discovery. | 251 | * move on with discovery. |
@@ -257,14 +254,14 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
257 | phba->fc_ratov = FF_DEF_RATOV; | 254 | phba->fc_ratov = FF_DEF_RATOV; |
258 | /* Start discovery - this should just do | 255 | /* Start discovery - this should just do |
259 | CLEAR_LA */ | 256 | CLEAR_LA */ |
260 | lpfc_disc_start(phba); | 257 | lpfc_disc_start(vport); |
261 | } else { | 258 | } else { |
262 | lpfc_initial_flogi(phba); | 259 | lpfc_initial_flogi(vport); |
263 | } | 260 | } |
264 | } else { | 261 | } else { |
265 | stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; | 262 | stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; |
266 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; | 263 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; |
267 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, | 264 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, |
268 | ndlp); | 265 | ndlp); |
269 | return 0; | 266 | return 0; |
270 | } | 267 | } |
@@ -272,11 +269,11 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
272 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 269 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
273 | lp = (uint32_t *) pcmd->virt; | 270 | lp = (uint32_t *) pcmd->virt; |
274 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 271 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
275 | if ((lpfc_check_sparm(phba, ndlp, sp, CLASS3) == 0)) { | 272 | if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3) == 0)) { |
276 | /* Reject this request because invalid parameters */ | 273 | /* Reject this request because invalid parameters */ |
277 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 274 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
278 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; | 275 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; |
279 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 276 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
280 | return 0; | 277 | return 0; |
281 | } | 278 | } |
282 | icmd = &cmdiocb->iocb; | 279 | icmd = &cmdiocb->iocb; |
@@ -290,12 +287,12 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
290 | ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, | 287 | ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, |
291 | ndlp->nlp_rpi); | 288 | ndlp->nlp_rpi); |
292 | 289 | ||
293 | if ((phba->cfg_fcp_class == 2) && | 290 | if (phba->cfg_fcp_class == 2 && sp->cls2.classValid) { |
294 | (sp->cls2.classValid)) { | ||
295 | ndlp->nlp_fcp_info |= CLASS2; | 291 | ndlp->nlp_fcp_info |= CLASS2; |
296 | } else { | 292 | } else { |
297 | ndlp->nlp_fcp_info |= CLASS3; | 293 | ndlp->nlp_fcp_info |= CLASS3; |
298 | } | 294 | } |
295 | |||
299 | ndlp->nlp_class_sup = 0; | 296 | ndlp->nlp_class_sup = 0; |
300 | if (sp->cls1.classValid) | 297 | if (sp->cls1.classValid) |
301 | ndlp->nlp_class_sup |= FC_COS_CLASS1; | 298 | ndlp->nlp_class_sup |= FC_COS_CLASS1; |
@@ -317,14 +314,14 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
317 | case NLP_STE_PRLI_ISSUE: | 314 | case NLP_STE_PRLI_ISSUE: |
318 | case NLP_STE_UNMAPPED_NODE: | 315 | case NLP_STE_UNMAPPED_NODE: |
319 | case NLP_STE_MAPPED_NODE: | 316 | case NLP_STE_MAPPED_NODE: |
320 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); | 317 | lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); |
321 | return 1; | 318 | return 1; |
322 | } | 319 | } |
323 | 320 | ||
324 | if ((phba->fc_flag & FC_PT2PT) | 321 | if ((vport->fc_flag & FC_PT2PT) |
325 | && !(phba->fc_flag & FC_PT2PT_PLOGI)) { | 322 | && !(vport->fc_flag & FC_PT2PT_PLOGI)) { |
326 | /* rcv'ed PLOGI decides what our NPortId will be */ | 323 | /* rcv'ed PLOGI decides what our NPortId will be */ |
327 | phba->fc_myDID = icmd->un.rcvels.parmRo; | 324 | vport->fc_myDID = icmd->un.rcvels.parmRo; |
328 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 325 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
329 | if (mbox == NULL) | 326 | if (mbox == NULL) |
330 | goto out; | 327 | goto out; |
@@ -337,15 +334,16 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
337 | goto out; | 334 | goto out; |
338 | } | 335 | } |
339 | 336 | ||
340 | lpfc_can_disctmo(phba); | 337 | lpfc_can_disctmo(vport); |
341 | } | 338 | } |
342 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 339 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
343 | if (mbox == NULL) | 340 | if (!mbox) |
344 | goto out; | 341 | goto out; |
345 | 342 | ||
346 | if (lpfc_reg_login(phba, icmd->un.rcvels.remoteID, | 343 | rc = lpfc_reg_login(phba, icmd->un.rcvels.remoteID, (uint8_t *) sp, |
347 | (uint8_t *) sp, mbox, 0)) { | 344 | mbox, 0); |
348 | mempool_free( mbox, phba->mbox_mem_pool); | 345 | if (rc) { |
346 | mempool_free(mbox, phba->mbox_mem_pool); | ||
349 | goto out; | 347 | goto out; |
350 | } | 348 | } |
351 | 349 | ||
@@ -357,7 +355,10 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
357 | * mbox->context2 = lpfc_nlp_get(ndlp) deferred until mailbox | 355 | * mbox->context2 = lpfc_nlp_get(ndlp) deferred until mailbox |
358 | * command issued in lpfc_cmpl_els_acc(). | 356 | * command issued in lpfc_cmpl_els_acc(). |
359 | */ | 357 | */ |
358 | mbox->vport = vport; | ||
359 | spin_lock_irq(shost->host_lock); | ||
360 | ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); | 360 | ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); |
361 | spin_unlock_irq(shost->host_lock); | ||
361 | 362 | ||
362 | /* | 363 | /* |
363 | * If there is an outstanding PLOGI issued, abort it before | 364 | * If there is an outstanding PLOGI issued, abort it before |
@@ -373,24 +374,24 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
373 | lpfc_els_abort(phba, ndlp); | 374 | lpfc_els_abort(phba, ndlp); |
374 | } | 375 | } |
375 | 376 | ||
376 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); | 377 | lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); |
377 | return 1; | 378 | return 1; |
378 | 379 | ||
379 | out: | 380 | out: |
380 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 381 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
381 | stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; | 382 | stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; |
382 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 383 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
383 | return 0; | 384 | return 0; |
384 | } | 385 | } |
385 | 386 | ||
386 | static int | 387 | static int |
387 | lpfc_rcv_padisc(struct lpfc_hba * phba, | 388 | lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
388 | struct lpfc_nodelist * ndlp, | ||
389 | struct lpfc_iocbq *cmdiocb) | 389 | struct lpfc_iocbq *cmdiocb) |
390 | { | 390 | { |
391 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
391 | struct lpfc_dmabuf *pcmd; | 392 | struct lpfc_dmabuf *pcmd; |
392 | struct serv_parm *sp; | 393 | struct serv_parm *sp; |
393 | struct lpfc_name *pnn, *ppn; | 394 | struct lpfc_name *pnn, *ppn; |
394 | struct ls_rjt stat; | 395 | struct ls_rjt stat; |
395 | ADISC *ap; | 396 | ADISC *ap; |
396 | IOCB_t *icmd; | 397 | IOCB_t *icmd; |
@@ -412,12 +413,11 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, | |||
412 | } | 413 | } |
413 | 414 | ||
414 | icmd = &cmdiocb->iocb; | 415 | icmd = &cmdiocb->iocb; |
415 | if ((icmd->ulpStatus == 0) && | 416 | if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) { |
416 | (lpfc_check_adisc(phba, ndlp, pnn, ppn))) { | ||
417 | if (cmd == ELS_CMD_ADISC) { | 417 | if (cmd == ELS_CMD_ADISC) { |
418 | lpfc_els_rsp_adisc_acc(phba, cmdiocb, ndlp); | 418 | lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp); |
419 | } else { | 419 | } else { |
420 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, | 420 | lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, |
421 | NULL, 0); | 421 | NULL, 0); |
422 | } | 422 | } |
423 | return 1; | 423 | return 1; |
@@ -427,55 +427,57 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, | |||
427 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 427 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
428 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; | 428 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; |
429 | stat.un.b.vendorUnique = 0; | 429 | stat.un.b.vendorUnique = 0; |
430 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 430 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
431 | 431 | ||
432 | /* 1 sec timeout */ | 432 | /* 1 sec timeout */ |
433 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 433 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
434 | 434 | ||
435 | spin_lock_irq(phba->host->host_lock); | 435 | spin_lock_irq(shost->host_lock); |
436 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 436 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
437 | spin_unlock_irq(phba->host->host_lock); | 437 | spin_unlock_irq(shost->host_lock); |
438 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 438 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
439 | ndlp->nlp_prev_state = ndlp->nlp_state; | 439 | ndlp->nlp_prev_state = ndlp->nlp_state; |
440 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 440 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
441 | return 0; | 441 | return 0; |
442 | } | 442 | } |
443 | 443 | ||
444 | static int | 444 | static int |
445 | lpfc_rcv_logo(struct lpfc_hba * phba, | 445 | lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
446 | struct lpfc_nodelist * ndlp, | 446 | struct lpfc_iocbq *cmdiocb, uint32_t els_cmd) |
447 | struct lpfc_iocbq *cmdiocb, | ||
448 | uint32_t els_cmd) | ||
449 | { | 447 | { |
450 | /* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */ | 448 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
449 | |||
450 | /* Put ndlp in NPR state with 1 sec timeout for plogi, ACC logo */ | ||
451 | /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary | 451 | /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary |
452 | * PLOGIs during LOGO storms from a device. | 452 | * PLOGIs during LOGO storms from a device. |
453 | */ | 453 | */ |
454 | spin_lock_irq(shost->host_lock); | ||
454 | ndlp->nlp_flag |= NLP_LOGO_ACC; | 455 | ndlp->nlp_flag |= NLP_LOGO_ACC; |
456 | spin_unlock_irq(shost->host_lock); | ||
455 | if (els_cmd == ELS_CMD_PRLO) | 457 | if (els_cmd == ELS_CMD_PRLO) |
456 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); | 458 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
457 | else | 459 | else |
458 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 460 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
459 | 461 | ||
460 | if (!(ndlp->nlp_type & NLP_FABRIC) || | 462 | if (!(ndlp->nlp_type & NLP_FABRIC) || |
461 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { | 463 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { |
462 | /* Only try to re-login if this is NOT a Fabric Node */ | 464 | /* Only try to re-login if this is NOT a Fabric Node */ |
463 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 465 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
464 | spin_lock_irq(phba->host->host_lock); | 466 | spin_lock_irq(shost->host_lock); |
465 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 467 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
466 | spin_unlock_irq(phba->host->host_lock); | 468 | spin_unlock_irq(shost->host_lock); |
467 | 469 | ||
468 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 470 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
469 | ndlp->nlp_prev_state = ndlp->nlp_state; | 471 | ndlp->nlp_prev_state = ndlp->nlp_state; |
470 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 472 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
471 | } else { | 473 | } else { |
472 | ndlp->nlp_prev_state = ndlp->nlp_state; | 474 | ndlp->nlp_prev_state = ndlp->nlp_state; |
473 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 475 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
474 | } | 476 | } |
475 | 477 | ||
476 | spin_lock_irq(phba->host->host_lock); | 478 | spin_lock_irq(shost->host_lock); |
477 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 479 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
478 | spin_unlock_irq(phba->host->host_lock); | 480 | spin_unlock_irq(shost->host_lock); |
479 | /* The driver has to wait until the ACC completes before it continues | 481 | /* The driver has to wait until the ACC completes before it continues |
480 | * processing the LOGO. The action will resume in | 482 | * processing the LOGO. The action will resume in |
481 | * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an | 483 | * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an |
@@ -485,9 +487,8 @@ lpfc_rcv_logo(struct lpfc_hba * phba, | |||
485 | } | 487 | } |
486 | 488 | ||
487 | static void | 489 | static void |
488 | lpfc_rcv_prli(struct lpfc_hba * phba, | 490 | lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
489 | struct lpfc_nodelist * ndlp, | 491 | struct lpfc_iocbq *cmdiocb) |
490 | struct lpfc_iocbq *cmdiocb) | ||
491 | { | 492 | { |
492 | struct lpfc_dmabuf *pcmd; | 493 | struct lpfc_dmabuf *pcmd; |
493 | uint32_t *lp; | 494 | uint32_t *lp; |
@@ -522,31 +523,33 @@ lpfc_rcv_prli(struct lpfc_hba * phba, | |||
522 | } | 523 | } |
523 | 524 | ||
524 | static uint32_t | 525 | static uint32_t |
525 | lpfc_disc_set_adisc(struct lpfc_hba * phba, | 526 | lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
526 | struct lpfc_nodelist * ndlp) | ||
527 | { | 527 | { |
528 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
529 | struct lpfc_hba *phba = vport->phba; | ||
530 | |||
528 | /* Check config parameter use-adisc or FCP-2 */ | 531 | /* Check config parameter use-adisc or FCP-2 */ |
529 | if ((phba->cfg_use_adisc == 0) && | 532 | if (phba->cfg_use_adisc == 0 && |
530 | !(phba->fc_flag & FC_RSCN_MODE)) { | 533 | (vport->fc_flag & FC_RSCN_MODE) == 0 && |
531 | if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) | 534 | (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) == 0) |
532 | return 0; | 535 | return 0; |
533 | } | 536 | |
534 | spin_lock_irq(phba->host->host_lock); | 537 | spin_lock_irq(shost->host_lock); |
535 | ndlp->nlp_flag |= NLP_NPR_ADISC; | 538 | ndlp->nlp_flag |= NLP_NPR_ADISC; |
536 | spin_unlock_irq(phba->host->host_lock); | 539 | spin_unlock_irq(shost->host_lock); |
537 | return 1; | 540 | return 1; |
538 | } | 541 | } |
539 | 542 | ||
540 | static uint32_t | 543 | static uint32_t |
541 | lpfc_disc_illegal(struct lpfc_hba * phba, | 544 | lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
542 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 545 | void *arg, uint32_t evt) |
543 | { | 546 | { |
544 | lpfc_printf_log(phba, | 547 | lpfc_printf_log(vport->phba, |
545 | KERN_ERR, | 548 | KERN_ERR, |
546 | LOG_DISCOVERY, | 549 | LOG_DISCOVERY, |
547 | "%d:0253 Illegal State Transition: node x%x event x%x, " | 550 | "%d:0253 Illegal State Transition: node x%x event x%x, " |
548 | "state x%x Data: x%x x%x\n", | 551 | "state x%x Data: x%x x%x\n", |
549 | phba->brd_no, | 552 | vport->phba->brd_no, |
550 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, | 553 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, |
551 | ndlp->nlp_flag); | 554 | ndlp->nlp_flag); |
552 | return ndlp->nlp_state; | 555 | return ndlp->nlp_state; |
@@ -555,86 +558,82 @@ lpfc_disc_illegal(struct lpfc_hba * phba, | |||
555 | /* Start of Discovery State Machine routines */ | 558 | /* Start of Discovery State Machine routines */ |
556 | 559 | ||
557 | static uint32_t | 560 | static uint32_t |
558 | lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba, | 561 | lpfc_rcv_plogi_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
559 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 562 | void *arg, uint32_t evt) |
560 | { | 563 | { |
561 | struct lpfc_iocbq *cmdiocb; | 564 | struct lpfc_iocbq *cmdiocb; |
562 | 565 | ||
563 | cmdiocb = (struct lpfc_iocbq *) arg; | 566 | cmdiocb = (struct lpfc_iocbq *) arg; |
564 | 567 | ||
565 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 568 | if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) { |
566 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | 569 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; |
567 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 570 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
568 | return ndlp->nlp_state; | 571 | return ndlp->nlp_state; |
569 | } | 572 | } |
570 | lpfc_drop_node(phba, ndlp); | 573 | lpfc_drop_node(vport, ndlp); |
571 | return NLP_STE_FREED_NODE; | 574 | return NLP_STE_FREED_NODE; |
572 | } | 575 | } |
573 | 576 | ||
574 | static uint32_t | 577 | static uint32_t |
575 | lpfc_rcv_els_unused_node(struct lpfc_hba * phba, | 578 | lpfc_rcv_els_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
576 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 579 | void *arg, uint32_t evt) |
577 | { | 580 | { |
578 | lpfc_issue_els_logo(phba, ndlp, 0); | 581 | lpfc_issue_els_logo(vport, ndlp, 0); |
579 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 582 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
580 | return ndlp->nlp_state; | 583 | return ndlp->nlp_state; |
581 | } | 584 | } |
582 | 585 | ||
583 | static uint32_t | 586 | static uint32_t |
584 | lpfc_rcv_logo_unused_node(struct lpfc_hba * phba, | 587 | lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
585 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 588 | void *arg, uint32_t evt) |
586 | { | 589 | { |
587 | struct lpfc_iocbq *cmdiocb; | 590 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
588 | 591 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; | |
589 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
590 | 592 | ||
591 | spin_lock_irq(phba->host->host_lock); | 593 | spin_lock_irq(shost->host_lock); |
592 | ndlp->nlp_flag |= NLP_LOGO_ACC; | 594 | ndlp->nlp_flag |= NLP_LOGO_ACC; |
593 | spin_unlock_irq(phba->host->host_lock); | 595 | spin_unlock_irq(shost->host_lock); |
594 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 596 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
595 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 597 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
596 | 598 | ||
597 | return ndlp->nlp_state; | 599 | return ndlp->nlp_state; |
598 | } | 600 | } |
599 | 601 | ||
600 | static uint32_t | 602 | static uint32_t |
601 | lpfc_cmpl_logo_unused_node(struct lpfc_hba * phba, | 603 | lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
602 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 604 | void *arg, uint32_t evt) |
603 | { | 605 | { |
604 | lpfc_drop_node(phba, ndlp); | 606 | lpfc_drop_node(vport, ndlp); |
605 | return NLP_STE_FREED_NODE; | 607 | return NLP_STE_FREED_NODE; |
606 | } | 608 | } |
607 | 609 | ||
608 | static uint32_t | 610 | static uint32_t |
609 | lpfc_device_rm_unused_node(struct lpfc_hba * phba, | 611 | lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
610 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 612 | void *arg, uint32_t evt) |
611 | { | 613 | { |
612 | lpfc_drop_node(phba, ndlp); | 614 | lpfc_drop_node(vport, ndlp); |
613 | return NLP_STE_FREED_NODE; | 615 | return NLP_STE_FREED_NODE; |
614 | } | 616 | } |
615 | 617 | ||
616 | static uint32_t | 618 | static uint32_t |
617 | lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | 619 | lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
618 | void *arg, uint32_t evt) | 620 | void *arg, uint32_t evt) |
619 | { | 621 | { |
622 | struct lpfc_hba *phba = vport->phba; | ||
620 | struct lpfc_iocbq *cmdiocb = arg; | 623 | struct lpfc_iocbq *cmdiocb = arg; |
621 | struct lpfc_dmabuf *pcmd; | 624 | struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
622 | struct serv_parm *sp; | 625 | uint32_t *lp = (uint32_t *) pcmd->virt; |
623 | uint32_t *lp; | 626 | struct serv_parm *sp = (struct serv_parm *) (lp + 1); |
624 | struct ls_rjt stat; | 627 | struct ls_rjt stat; |
625 | int port_cmp; | 628 | int port_cmp; |
626 | 629 | ||
627 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
628 | lp = (uint32_t *) pcmd->virt; | ||
629 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | ||
630 | |||
631 | memset(&stat, 0, sizeof (struct ls_rjt)); | 630 | memset(&stat, 0, sizeof (struct ls_rjt)); |
632 | 631 | ||
633 | /* For a PLOGI, we only accept if our portname is less | 632 | /* For a PLOGI, we only accept if our portname is less |
634 | * than the remote portname. | 633 | * than the remote portname. |
635 | */ | 634 | */ |
636 | phba->fc_stat.elsLogiCol++; | 635 | phba->fc_stat.elsLogiCol++; |
637 | port_cmp = memcmp(&phba->fc_portname, &sp->portName, | 636 | port_cmp = memcmp(&vport->fc_portname, &sp->portName, |
638 | sizeof (struct lpfc_name)); | 637 | sizeof (struct lpfc_name)); |
639 | 638 | ||
640 | if (port_cmp >= 0) { | 639 | if (port_cmp >= 0) { |
@@ -642,64 +641,64 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
642 | ours */ | 641 | ours */ |
643 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 642 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
644 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; | 643 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; |
645 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 644 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
646 | } else { | 645 | } else { |
647 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 646 | lpfc_rcv_plogi(vport, ndlp, cmdiocb); |
648 | } /* if our portname was less */ | 647 | } /* If our portname was less */ |
649 | 648 | ||
650 | return ndlp->nlp_state; | 649 | return ndlp->nlp_state; |
651 | } | 650 | } |
652 | 651 | ||
653 | static uint32_t | 652 | static uint32_t |
654 | lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba, | 653 | lpfc_rcv_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
655 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 654 | void *arg, uint32_t evt) |
656 | { | 655 | { |
657 | struct lpfc_iocbq *cmdiocb; | 656 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
658 | |||
659 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
660 | 657 | ||
661 | /* software abort outstanding PLOGI */ | 658 | /* software abort outstanding PLOGI */ |
662 | lpfc_els_abort(phba, ndlp); | 659 | lpfc_els_abort(vport->phba, ndlp); |
663 | 660 | ||
664 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 661 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
665 | return ndlp->nlp_state; | 662 | return ndlp->nlp_state; |
666 | } | 663 | } |
667 | 664 | ||
668 | static uint32_t | 665 | static uint32_t |
669 | lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, | 666 | lpfc_rcv_els_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
670 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 667 | void *arg, uint32_t evt) |
671 | { | 668 | { |
672 | struct lpfc_iocbq *cmdiocb; | 669 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
673 | 670 | struct lpfc_hba *phba = vport->phba; | |
674 | cmdiocb = (struct lpfc_iocbq *) arg; | 671 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
675 | 672 | ||
676 | /* software abort outstanding PLOGI */ | 673 | /* software abort outstanding PLOGI */ |
677 | lpfc_els_abort(phba, ndlp); | 674 | lpfc_els_abort(phba, ndlp); |
678 | 675 | ||
679 | if (evt == NLP_EVT_RCV_LOGO) { | 676 | if (evt == NLP_EVT_RCV_LOGO) { |
680 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 677 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
681 | } else { | 678 | } else { |
682 | lpfc_issue_els_logo(phba, ndlp, 0); | 679 | lpfc_issue_els_logo(vport, ndlp, 0); |
683 | } | 680 | } |
684 | 681 | ||
685 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 682 | /* Put ndlp in npr state set plogi timer for 1 sec */ |
686 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 683 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
687 | spin_lock_irq(phba->host->host_lock); | 684 | spin_lock_irq(shost->host_lock); |
688 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 685 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
689 | spin_unlock_irq(phba->host->host_lock); | 686 | spin_unlock_irq(shost->host_lock); |
690 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 687 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
691 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; | 688 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; |
692 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 689 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
693 | 690 | ||
694 | return ndlp->nlp_state; | 691 | return ndlp->nlp_state; |
695 | } | 692 | } |
696 | 693 | ||
697 | static uint32_t | 694 | static uint32_t |
698 | lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | 695 | lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, |
699 | struct lpfc_nodelist * ndlp, void *arg, | 696 | struct lpfc_nodelist *ndlp, |
697 | void *arg, | ||
700 | uint32_t evt) | 698 | uint32_t evt) |
701 | { | 699 | { |
702 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 700 | struct lpfc_hba *phba = vport->phba; |
701 | struct lpfc_iocbq *cmdiocb, *rspiocb; | ||
703 | struct lpfc_dmabuf *pcmd, *prsp, *mp; | 702 | struct lpfc_dmabuf *pcmd, *prsp, *mp; |
704 | uint32_t *lp; | 703 | uint32_t *lp; |
705 | IOCB_t *irsp; | 704 | IOCB_t *irsp; |
@@ -721,13 +720,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
721 | 720 | ||
722 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 721 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
723 | 722 | ||
724 | prsp = list_get_first(&pcmd->list, | 723 | prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list); |
725 | struct lpfc_dmabuf, | ||
726 | list); | ||
727 | lp = (uint32_t *) prsp->virt; | ||
728 | 724 | ||
725 | lp = (uint32_t *) prsp->virt; | ||
729 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 726 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
730 | if (!lpfc_check_sparm(phba, ndlp, sp, CLASS3)) | 727 | if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3)) |
731 | goto out; | 728 | goto out; |
732 | 729 | ||
733 | /* PLOGI chkparm OK */ | 730 | /* PLOGI chkparm OK */ |
@@ -740,12 +737,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
740 | ndlp->nlp_DID, ndlp->nlp_state, | 737 | ndlp->nlp_DID, ndlp->nlp_state, |
741 | ndlp->nlp_flag, ndlp->nlp_rpi); | 738 | ndlp->nlp_flag, ndlp->nlp_rpi); |
742 | 739 | ||
743 | if ((phba->cfg_fcp_class == 2) && | 740 | if (phba->cfg_fcp_class == 2 && (sp->cls2.classValid)) |
744 | (sp->cls2.classValid)) { | ||
745 | ndlp->nlp_fcp_info |= CLASS2; | 741 | ndlp->nlp_fcp_info |= CLASS2; |
746 | } else { | 742 | else |
747 | ndlp->nlp_fcp_info |= CLASS3; | 743 | ndlp->nlp_fcp_info |= CLASS3; |
748 | } | 744 | |
749 | ndlp->nlp_class_sup = 0; | 745 | ndlp->nlp_class_sup = 0; |
750 | if (sp->cls1.classValid) | 746 | if (sp->cls1.classValid) |
751 | ndlp->nlp_class_sup |= FC_COS_CLASS1; | 747 | ndlp->nlp_class_sup |= FC_COS_CLASS1; |
@@ -756,14 +752,14 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
756 | if (sp->cls4.classValid) | 752 | if (sp->cls4.classValid) |
757 | ndlp->nlp_class_sup |= FC_COS_CLASS4; | 753 | ndlp->nlp_class_sup |= FC_COS_CLASS4; |
758 | ndlp->nlp_maxframe = | 754 | ndlp->nlp_maxframe = |
759 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | | 755 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; |
760 | sp->cmn.bbRcvSizeLsb; | ||
761 | 756 | ||
762 | if (!(mbox = mempool_alloc(phba->mbox_mem_pool, | 757 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
763 | GFP_KERNEL))) | 758 | if (!mbox) |
764 | goto out; | 759 | goto out; |
765 | 760 | ||
766 | lpfc_unreg_rpi(phba, ndlp); | 761 | lpfc_unreg_rpi(vport, ndlp); |
762 | |||
767 | if (lpfc_reg_login(phba, irsp->un.elsreq64.remoteID, (uint8_t *) sp, | 763 | if (lpfc_reg_login(phba, irsp->un.elsreq64.remoteID, (uint8_t *) sp, |
768 | mbox, 0) == 0) { | 764 | mbox, 0) == 0) { |
769 | switch (ndlp->nlp_DID) { | 765 | switch (ndlp->nlp_DID) { |
@@ -777,10 +773,12 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
777 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | 773 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
778 | } | 774 | } |
779 | mbox->context2 = lpfc_nlp_get(ndlp); | 775 | mbox->context2 = lpfc_nlp_get(ndlp); |
776 | mbox->vport = vport; | ||
780 | if (lpfc_sli_issue_mbox(phba, mbox, | 777 | if (lpfc_sli_issue_mbox(phba, mbox, |
781 | (MBX_NOWAIT | MBX_STOP_IOCB)) | 778 | (MBX_NOWAIT | MBX_STOP_IOCB)) |
782 | != MBX_NOT_FINISHED) { | 779 | != MBX_NOT_FINISHED) { |
783 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE); | 780 | lpfc_nlp_set_state(vport, ndlp, |
781 | NLP_STE_REG_LOGIN_ISSUE); | ||
784 | return ndlp->nlp_state; | 782 | return ndlp->nlp_state; |
785 | } | 783 | } |
786 | lpfc_nlp_put(ndlp); | 784 | lpfc_nlp_put(ndlp); |
@@ -796,49 +794,56 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
796 | out: | 794 | out: |
797 | /* Free this node since the driver cannot login or has the wrong | 795 | /* Free this node since the driver cannot login or has the wrong |
798 | sparm */ | 796 | sparm */ |
799 | lpfc_drop_node(phba, ndlp); | 797 | lpfc_drop_node(vport, ndlp); |
800 | return NLP_STE_FREED_NODE; | 798 | return NLP_STE_FREED_NODE; |
801 | } | 799 | } |
802 | 800 | ||
803 | static uint32_t | 801 | static uint32_t |
804 | lpfc_device_rm_plogi_issue(struct lpfc_hba * phba, | 802 | lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
805 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 803 | void *arg, uint32_t evt) |
806 | { | 804 | { |
807 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 805 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
806 | |||
807 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
808 | spin_lock_irq(shost->host_lock); | ||
808 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | 809 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
810 | spin_unlock_irq(shost->host_lock); | ||
809 | return ndlp->nlp_state; | 811 | return ndlp->nlp_state; |
810 | } | 812 | } else { |
811 | else { | ||
812 | /* software abort outstanding PLOGI */ | 813 | /* software abort outstanding PLOGI */ |
813 | lpfc_els_abort(phba, ndlp); | 814 | lpfc_els_abort(vport->phba, ndlp); |
814 | 815 | ||
815 | lpfc_drop_node(phba, ndlp); | 816 | lpfc_drop_node(vport, ndlp); |
816 | return NLP_STE_FREED_NODE; | 817 | return NLP_STE_FREED_NODE; |
817 | } | 818 | } |
818 | } | 819 | } |
819 | 820 | ||
820 | static uint32_t | 821 | static uint32_t |
821 | lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, | 822 | lpfc_device_recov_plogi_issue(struct lpfc_vport *vport, |
822 | struct lpfc_nodelist * ndlp, void *arg, | 823 | struct lpfc_nodelist *ndlp, |
823 | uint32_t evt) | 824 | void *arg, |
825 | uint32_t evt) | ||
824 | { | 826 | { |
827 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
828 | struct lpfc_hba *phba = vport->phba; | ||
829 | |||
825 | /* software abort outstanding PLOGI */ | 830 | /* software abort outstanding PLOGI */ |
826 | lpfc_els_abort(phba, ndlp); | 831 | lpfc_els_abort(phba, ndlp); |
827 | 832 | ||
828 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; | 833 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; |
829 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 834 | spin_lock_irq(shost->host_lock); |
830 | spin_lock_irq(phba->host->host_lock); | 835 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
831 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 836 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
832 | spin_unlock_irq(phba->host->host_lock); | 837 | spin_unlock_irq(shost->host_lock); |
833 | 838 | ||
834 | return ndlp->nlp_state; | 839 | return ndlp->nlp_state; |
835 | } | 840 | } |
836 | 841 | ||
837 | static uint32_t | 842 | static uint32_t |
838 | lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, | 843 | lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
839 | struct lpfc_nodelist * ndlp, void *arg, | 844 | void *arg, uint32_t evt) |
840 | uint32_t evt) | ||
841 | { | 845 | { |
846 | struct lpfc_hba *phba = vport->phba; | ||
842 | struct lpfc_iocbq *cmdiocb; | 847 | struct lpfc_iocbq *cmdiocb; |
843 | 848 | ||
844 | /* software abort outstanding ADISC */ | 849 | /* software abort outstanding ADISC */ |
@@ -846,34 +851,31 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, | |||
846 | 851 | ||
847 | cmdiocb = (struct lpfc_iocbq *) arg; | 852 | cmdiocb = (struct lpfc_iocbq *) arg; |
848 | 853 | ||
849 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 854 | if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) |
850 | return ndlp->nlp_state; | 855 | return ndlp->nlp_state; |
851 | } | 856 | |
852 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 857 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
853 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 858 | lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); |
854 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 859 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
855 | 860 | ||
856 | return ndlp->nlp_state; | 861 | return ndlp->nlp_state; |
857 | } | 862 | } |
858 | 863 | ||
859 | static uint32_t | 864 | static uint32_t |
860 | lpfc_rcv_prli_adisc_issue(struct lpfc_hba * phba, | 865 | lpfc_rcv_prli_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
861 | struct lpfc_nodelist * ndlp, void *arg, | 866 | void *arg, uint32_t evt) |
862 | uint32_t evt) | ||
863 | { | 867 | { |
864 | struct lpfc_iocbq *cmdiocb; | 868 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
865 | |||
866 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
867 | 869 | ||
868 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 870 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); |
869 | return ndlp->nlp_state; | 871 | return ndlp->nlp_state; |
870 | } | 872 | } |
871 | 873 | ||
872 | static uint32_t | 874 | static uint32_t |
873 | lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, | 875 | lpfc_rcv_logo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
874 | struct lpfc_nodelist * ndlp, void *arg, | 876 | void *arg, uint32_t evt) |
875 | uint32_t evt) | ||
876 | { | 877 | { |
878 | struct lpfc_hba *phba = vport->phba; | ||
877 | struct lpfc_iocbq *cmdiocb; | 879 | struct lpfc_iocbq *cmdiocb; |
878 | 880 | ||
879 | cmdiocb = (struct lpfc_iocbq *) arg; | 881 | cmdiocb = (struct lpfc_iocbq *) arg; |
@@ -881,42 +883,43 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, | |||
881 | /* software abort outstanding ADISC */ | 883 | /* software abort outstanding ADISC */ |
882 | lpfc_els_abort(phba, ndlp); | 884 | lpfc_els_abort(phba, ndlp); |
883 | 885 | ||
884 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 886 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
885 | return ndlp->nlp_state; | 887 | return ndlp->nlp_state; |
886 | } | 888 | } |
887 | 889 | ||
888 | static uint32_t | 890 | static uint32_t |
889 | lpfc_rcv_padisc_adisc_issue(struct lpfc_hba * phba, | 891 | lpfc_rcv_padisc_adisc_issue(struct lpfc_vport *vport, |
890 | struct lpfc_nodelist * ndlp, void *arg, | 892 | struct lpfc_nodelist *ndlp, |
891 | uint32_t evt) | 893 | void *arg, uint32_t evt) |
892 | { | 894 | { |
893 | struct lpfc_iocbq *cmdiocb; | 895 | struct lpfc_iocbq *cmdiocb; |
894 | 896 | ||
895 | cmdiocb = (struct lpfc_iocbq *) arg; | 897 | cmdiocb = (struct lpfc_iocbq *) arg; |
896 | 898 | ||
897 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 899 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
898 | return ndlp->nlp_state; | 900 | return ndlp->nlp_state; |
899 | } | 901 | } |
900 | 902 | ||
901 | static uint32_t | 903 | static uint32_t |
902 | lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba, | 904 | lpfc_rcv_prlo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
903 | struct lpfc_nodelist * ndlp, void *arg, | 905 | void *arg, uint32_t evt) |
904 | uint32_t evt) | ||
905 | { | 906 | { |
906 | struct lpfc_iocbq *cmdiocb; | 907 | struct lpfc_iocbq *cmdiocb; |
907 | 908 | ||
908 | cmdiocb = (struct lpfc_iocbq *) arg; | 909 | cmdiocb = (struct lpfc_iocbq *) arg; |
909 | 910 | ||
910 | /* Treat like rcv logo */ | 911 | /* Treat like rcv logo */ |
911 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO); | 912 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO); |
912 | return ndlp->nlp_state; | 913 | return ndlp->nlp_state; |
913 | } | 914 | } |
914 | 915 | ||
915 | static uint32_t | 916 | static uint32_t |
916 | lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, | 917 | lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport, |
917 | struct lpfc_nodelist * ndlp, void *arg, | 918 | struct lpfc_nodelist *ndlp, |
918 | uint32_t evt) | 919 | void *arg, uint32_t evt) |
919 | { | 920 | { |
921 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
922 | struct lpfc_hba *phba = vport->phba; | ||
920 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 923 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
921 | IOCB_t *irsp; | 924 | IOCB_t *irsp; |
922 | ADISC *ap; | 925 | ADISC *ap; |
@@ -928,101 +931,107 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, | |||
928 | irsp = &rspiocb->iocb; | 931 | irsp = &rspiocb->iocb; |
929 | 932 | ||
930 | if ((irsp->ulpStatus) || | 933 | if ((irsp->ulpStatus) || |
931 | (!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) { | 934 | (!lpfc_check_adisc(vport, ndlp, &ap->nodeName, &ap->portName))) { |
932 | /* 1 sec timeout */ | 935 | /* 1 sec timeout */ |
933 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 936 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
934 | spin_lock_irq(phba->host->host_lock); | 937 | spin_lock_irq(shost->host_lock); |
935 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 938 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
936 | spin_unlock_irq(phba->host->host_lock); | 939 | spin_unlock_irq(shost->host_lock); |
937 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 940 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
938 | 941 | ||
939 | memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name)); | 942 | memset(&ndlp->nlp_nodename, 0, sizeof(struct lpfc_name)); |
940 | memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); | 943 | memset(&ndlp->nlp_portname, 0, sizeof(struct lpfc_name)); |
941 | 944 | ||
942 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 945 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
943 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 946 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
944 | lpfc_unreg_rpi(phba, ndlp); | 947 | lpfc_unreg_rpi(vport, ndlp); |
945 | return ndlp->nlp_state; | 948 | return ndlp->nlp_state; |
946 | } | 949 | } |
947 | 950 | ||
948 | if (ndlp->nlp_type & NLP_FCP_TARGET) { | 951 | if (ndlp->nlp_type & NLP_FCP_TARGET) { |
949 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 952 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
950 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_MAPPED_NODE); | 953 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE); |
951 | } else { | 954 | } else { |
952 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 955 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
953 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 956 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
954 | } | 957 | } |
955 | return ndlp->nlp_state; | 958 | return ndlp->nlp_state; |
956 | } | 959 | } |
957 | 960 | ||
958 | static uint32_t | 961 | static uint32_t |
959 | lpfc_device_rm_adisc_issue(struct lpfc_hba * phba, | 962 | lpfc_device_rm_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
960 | struct lpfc_nodelist * ndlp, void *arg, | 963 | void *arg, uint32_t evt) |
961 | uint32_t evt) | ||
962 | { | 964 | { |
963 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 965 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
966 | |||
967 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
968 | spin_lock_irq(shost->host_lock); | ||
964 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | 969 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
970 | spin_unlock_irq(shost->host_lock); | ||
965 | return ndlp->nlp_state; | 971 | return ndlp->nlp_state; |
966 | } | 972 | } else { |
967 | else { | ||
968 | /* software abort outstanding ADISC */ | 973 | /* software abort outstanding ADISC */ |
969 | lpfc_els_abort(phba, ndlp); | 974 | lpfc_els_abort(vport->phba, ndlp); |
970 | 975 | ||
971 | lpfc_drop_node(phba, ndlp); | 976 | lpfc_drop_node(vport, ndlp); |
972 | return NLP_STE_FREED_NODE; | 977 | return NLP_STE_FREED_NODE; |
973 | } | 978 | } |
974 | } | 979 | } |
975 | 980 | ||
976 | static uint32_t | 981 | static uint32_t |
977 | lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, | 982 | lpfc_device_recov_adisc_issue(struct lpfc_vport *vport, |
978 | struct lpfc_nodelist * ndlp, void *arg, | 983 | struct lpfc_nodelist *ndlp, |
979 | uint32_t evt) | 984 | void *arg, |
985 | uint32_t evt) | ||
980 | { | 986 | { |
987 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
988 | struct lpfc_hba *phba = vport->phba; | ||
989 | |||
981 | /* software abort outstanding ADISC */ | 990 | /* software abort outstanding ADISC */ |
982 | lpfc_els_abort(phba, ndlp); | 991 | lpfc_els_abort(phba, ndlp); |
983 | 992 | ||
984 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 993 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
985 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 994 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
986 | spin_lock_irq(phba->host->host_lock); | 995 | spin_lock_irq(shost->host_lock); |
987 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 996 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
988 | ndlp->nlp_flag |= NLP_NPR_ADISC; | 997 | ndlp->nlp_flag |= NLP_NPR_ADISC; |
989 | spin_unlock_irq(phba->host->host_lock); | 998 | spin_unlock_irq(shost->host_lock); |
990 | 999 | ||
991 | return ndlp->nlp_state; | 1000 | return ndlp->nlp_state; |
992 | } | 1001 | } |
993 | 1002 | ||
994 | static uint32_t | 1003 | static uint32_t |
995 | lpfc_rcv_plogi_reglogin_issue(struct lpfc_hba * phba, | 1004 | lpfc_rcv_plogi_reglogin_issue(struct lpfc_vport *vport, |
996 | struct lpfc_nodelist * ndlp, void *arg, | 1005 | struct lpfc_nodelist *ndlp, |
1006 | void *arg, | ||
997 | uint32_t evt) | 1007 | uint32_t evt) |
998 | { | 1008 | { |
999 | struct lpfc_iocbq *cmdiocb; | 1009 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1000 | |||
1001 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1002 | 1010 | ||
1003 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1011 | lpfc_rcv_plogi(vport, ndlp, cmdiocb); |
1004 | return ndlp->nlp_state; | 1012 | return ndlp->nlp_state; |
1005 | } | 1013 | } |
1006 | 1014 | ||
1007 | static uint32_t | 1015 | static uint32_t |
1008 | lpfc_rcv_prli_reglogin_issue(struct lpfc_hba * phba, | 1016 | lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport, |
1009 | struct lpfc_nodelist * ndlp, void *arg, | 1017 | struct lpfc_nodelist *ndlp, |
1018 | void *arg, | ||
1010 | uint32_t evt) | 1019 | uint32_t evt) |
1011 | { | 1020 | { |
1012 | struct lpfc_iocbq *cmdiocb; | 1021 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1013 | |||
1014 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1015 | 1022 | ||
1016 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1023 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); |
1017 | return ndlp->nlp_state; | 1024 | return ndlp->nlp_state; |
1018 | } | 1025 | } |
1019 | 1026 | ||
1020 | static uint32_t | 1027 | static uint32_t |
1021 | lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, | 1028 | lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport, |
1022 | struct lpfc_nodelist * ndlp, void *arg, | 1029 | struct lpfc_nodelist *ndlp, |
1030 | void *arg, | ||
1023 | uint32_t evt) | 1031 | uint32_t evt) |
1024 | { | 1032 | { |
1025 | struct lpfc_iocbq *cmdiocb; | 1033 | struct lpfc_hba *phba = vport->phba; |
1034 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; | ||
1026 | LPFC_MBOXQ_t *mb; | 1035 | LPFC_MBOXQ_t *mb; |
1027 | LPFC_MBOXQ_t *nextmb; | 1036 | LPFC_MBOXQ_t *nextmb; |
1028 | struct lpfc_dmabuf *mp; | 1037 | struct lpfc_dmabuf *mp; |
@@ -1038,7 +1047,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, | |||
1038 | } | 1047 | } |
1039 | } | 1048 | } |
1040 | 1049 | ||
1041 | spin_lock_irq(phba->host->host_lock); | 1050 | spin_lock_irq(&phba->hbalock); |
1042 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { | 1051 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { |
1043 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 1052 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && |
1044 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 1053 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
@@ -1051,49 +1060,49 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, | |||
1051 | mempool_free(mb, phba->mbox_mem_pool); | 1060 | mempool_free(mb, phba->mbox_mem_pool); |
1052 | } | 1061 | } |
1053 | } | 1062 | } |
1054 | spin_unlock_irq(phba->host->host_lock); | 1063 | spin_unlock_irq(&phba->hbalock); |
1055 | 1064 | ||
1056 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 1065 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
1057 | return ndlp->nlp_state; | 1066 | return ndlp->nlp_state; |
1058 | } | 1067 | } |
1059 | 1068 | ||
1060 | static uint32_t | 1069 | static uint32_t |
1061 | lpfc_rcv_padisc_reglogin_issue(struct lpfc_hba * phba, | 1070 | lpfc_rcv_padisc_reglogin_issue(struct lpfc_vport *vport, |
1062 | struct lpfc_nodelist * ndlp, void *arg, | 1071 | struct lpfc_nodelist *ndlp, |
1072 | void *arg, | ||
1063 | uint32_t evt) | 1073 | uint32_t evt) |
1064 | { | 1074 | { |
1065 | struct lpfc_iocbq *cmdiocb; | 1075 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1066 | 1076 | ||
1067 | cmdiocb = (struct lpfc_iocbq *) arg; | 1077 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
1068 | |||
1069 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | ||
1070 | return ndlp->nlp_state; | 1078 | return ndlp->nlp_state; |
1071 | } | 1079 | } |
1072 | 1080 | ||
1073 | static uint32_t | 1081 | static uint32_t |
1074 | lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba, | 1082 | lpfc_rcv_prlo_reglogin_issue(struct lpfc_vport *vport, |
1075 | struct lpfc_nodelist * ndlp, void *arg, | 1083 | struct lpfc_nodelist *ndlp, |
1084 | void *arg, | ||
1076 | uint32_t evt) | 1085 | uint32_t evt) |
1077 | { | 1086 | { |
1078 | struct lpfc_iocbq *cmdiocb; | 1087 | struct lpfc_iocbq *cmdiocb; |
1079 | 1088 | ||
1080 | cmdiocb = (struct lpfc_iocbq *) arg; | 1089 | cmdiocb = (struct lpfc_iocbq *) arg; |
1081 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); | 1090 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
1082 | return ndlp->nlp_state; | 1091 | return ndlp->nlp_state; |
1083 | } | 1092 | } |
1084 | 1093 | ||
1085 | static uint32_t | 1094 | static uint32_t |
1086 | lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | 1095 | lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, |
1087 | struct lpfc_nodelist * ndlp, | 1096 | struct lpfc_nodelist *ndlp, |
1088 | void *arg, uint32_t evt) | 1097 | void *arg, |
1098 | uint32_t evt) | ||
1089 | { | 1099 | { |
1090 | LPFC_MBOXQ_t *pmb; | 1100 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1091 | MAILBOX_t *mb; | 1101 | struct lpfc_hba *phba = vport->phba; |
1092 | uint32_t did; | 1102 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; |
1103 | MAILBOX_t *mb = &pmb->mb; | ||
1104 | uint32_t did = mb->un.varWords[1]; | ||
1093 | 1105 | ||
1094 | pmb = (LPFC_MBOXQ_t *) arg; | ||
1095 | mb = &pmb->mb; | ||
1096 | did = mb->un.varWords[1]; | ||
1097 | if (mb->mbxStatus) { | 1106 | if (mb->mbxStatus) { |
1098 | /* RegLogin failed */ | 1107 | /* RegLogin failed */ |
1099 | lpfc_printf_log(phba, | 1108 | lpfc_printf_log(phba, |
@@ -1101,7 +1110,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1101 | LOG_DISCOVERY, | 1110 | LOG_DISCOVERY, |
1102 | "%d:0246 RegLogin failed Data: x%x x%x x%x\n", | 1111 | "%d:0246 RegLogin failed Data: x%x x%x x%x\n", |
1103 | phba->brd_no, | 1112 | phba->brd_no, |
1104 | did, mb->mbxStatus, phba->hba_state); | 1113 | did, mb->mbxStatus, vport->port_state); |
1105 | 1114 | ||
1106 | /* | 1115 | /* |
1107 | * If RegLogin failed due to lack of HBA resources do not | 1116 | * If RegLogin failed due to lack of HBA resources do not |
@@ -1109,20 +1118,20 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1109 | */ | 1118 | */ |
1110 | if (mb->mbxStatus == MBXERR_RPI_FULL) { | 1119 | if (mb->mbxStatus == MBXERR_RPI_FULL) { |
1111 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | 1120 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; |
1112 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 1121 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
1113 | return ndlp->nlp_state; | 1122 | return ndlp->nlp_state; |
1114 | } | 1123 | } |
1115 | 1124 | ||
1116 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 1125 | /* Put ndlp in npr state set plogi timer for 1 sec */ |
1117 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 1126 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
1118 | spin_lock_irq(phba->host->host_lock); | 1127 | spin_lock_irq(shost->host_lock); |
1119 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1128 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1120 | spin_unlock_irq(phba->host->host_lock); | 1129 | spin_unlock_irq(shost->host_lock); |
1121 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 1130 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
1122 | 1131 | ||
1123 | lpfc_issue_els_logo(phba, ndlp, 0); | 1132 | lpfc_issue_els_logo(vport, ndlp, 0); |
1124 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | 1133 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1125 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1134 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1126 | return ndlp->nlp_state; | 1135 | return ndlp->nlp_state; |
1127 | } | 1136 | } |
1128 | 1137 | ||
@@ -1131,91 +1140,92 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1131 | /* Only if we are not a fabric nport do we issue PRLI */ | 1140 | /* Only if we are not a fabric nport do we issue PRLI */ |
1132 | if (!(ndlp->nlp_type & NLP_FABRIC)) { | 1141 | if (!(ndlp->nlp_type & NLP_FABRIC)) { |
1133 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | 1142 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1134 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PRLI_ISSUE); | 1143 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); |
1135 | lpfc_issue_els_prli(phba, ndlp, 0); | 1144 | lpfc_issue_els_prli(vport, ndlp, 0); |
1136 | } else { | 1145 | } else { |
1137 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | 1146 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1138 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 1147 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1139 | } | 1148 | } |
1140 | return ndlp->nlp_state; | 1149 | return ndlp->nlp_state; |
1141 | } | 1150 | } |
1142 | 1151 | ||
1143 | static uint32_t | 1152 | static uint32_t |
1144 | lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba, | 1153 | lpfc_device_rm_reglogin_issue(struct lpfc_vport *vport, |
1145 | struct lpfc_nodelist * ndlp, void *arg, | 1154 | struct lpfc_nodelist *ndlp, |
1155 | void *arg, | ||
1146 | uint32_t evt) | 1156 | uint32_t evt) |
1147 | { | 1157 | { |
1148 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 1158 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1159 | |||
1160 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
1161 | spin_lock_irq(shost->host_lock); | ||
1149 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | 1162 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
1163 | spin_unlock_irq(shost->host_lock); | ||
1150 | return ndlp->nlp_state; | 1164 | return ndlp->nlp_state; |
1151 | } | 1165 | } else { |
1152 | else { | 1166 | lpfc_drop_node(vport, ndlp); |
1153 | lpfc_drop_node(phba, ndlp); | ||
1154 | return NLP_STE_FREED_NODE; | 1167 | return NLP_STE_FREED_NODE; |
1155 | } | 1168 | } |
1156 | } | 1169 | } |
1157 | 1170 | ||
1158 | static uint32_t | 1171 | static uint32_t |
1159 | lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, | 1172 | lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport, |
1160 | struct lpfc_nodelist * ndlp, void *arg, | 1173 | struct lpfc_nodelist *ndlp, |
1161 | uint32_t evt) | 1174 | void *arg, |
1175 | uint32_t evt) | ||
1162 | { | 1176 | { |
1177 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1178 | |||
1163 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | 1179 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1164 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1180 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1165 | spin_lock_irq(phba->host->host_lock); | 1181 | spin_lock_irq(shost->host_lock); |
1166 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1182 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1167 | spin_unlock_irq(phba->host->host_lock); | 1183 | spin_unlock_irq(shost->host_lock); |
1168 | return ndlp->nlp_state; | 1184 | return ndlp->nlp_state; |
1169 | } | 1185 | } |
1170 | 1186 | ||
1171 | static uint32_t | 1187 | static uint32_t |
1172 | lpfc_rcv_plogi_prli_issue(struct lpfc_hba * phba, | 1188 | lpfc_rcv_plogi_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1173 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1189 | void *arg, uint32_t evt) |
1174 | { | 1190 | { |
1175 | struct lpfc_iocbq *cmdiocb; | 1191 | struct lpfc_iocbq *cmdiocb; |
1176 | 1192 | ||
1177 | cmdiocb = (struct lpfc_iocbq *) arg; | 1193 | cmdiocb = (struct lpfc_iocbq *) arg; |
1178 | 1194 | ||
1179 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1195 | lpfc_rcv_plogi(vport, ndlp, cmdiocb); |
1180 | return ndlp->nlp_state; | 1196 | return ndlp->nlp_state; |
1181 | } | 1197 | } |
1182 | 1198 | ||
1183 | static uint32_t | 1199 | static uint32_t |
1184 | lpfc_rcv_prli_prli_issue(struct lpfc_hba * phba, | 1200 | lpfc_rcv_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1185 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1201 | void *arg, uint32_t evt) |
1186 | { | 1202 | { |
1187 | struct lpfc_iocbq *cmdiocb; | 1203 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1188 | |||
1189 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1190 | 1204 | ||
1191 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1205 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); |
1192 | return ndlp->nlp_state; | 1206 | return ndlp->nlp_state; |
1193 | } | 1207 | } |
1194 | 1208 | ||
1195 | static uint32_t | 1209 | static uint32_t |
1196 | lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba, | 1210 | lpfc_rcv_logo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1197 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1211 | void *arg, uint32_t evt) |
1198 | { | 1212 | { |
1199 | struct lpfc_iocbq *cmdiocb; | 1213 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1200 | |||
1201 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1202 | 1214 | ||
1203 | /* Software abort outstanding PRLI before sending acc */ | 1215 | /* Software abort outstanding PRLI before sending acc */ |
1204 | lpfc_els_abort(phba, ndlp); | 1216 | lpfc_els_abort(vport->phba, ndlp); |
1205 | 1217 | ||
1206 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 1218 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
1207 | return ndlp->nlp_state; | 1219 | return ndlp->nlp_state; |
1208 | } | 1220 | } |
1209 | 1221 | ||
1210 | static uint32_t | 1222 | static uint32_t |
1211 | lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba, | 1223 | lpfc_rcv_padisc_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1212 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1224 | void *arg, uint32_t evt) |
1213 | { | 1225 | { |
1214 | struct lpfc_iocbq *cmdiocb; | 1226 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1215 | |||
1216 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1217 | 1227 | ||
1218 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1228 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
1219 | return ndlp->nlp_state; | 1229 | return ndlp->nlp_state; |
1220 | } | 1230 | } |
1221 | 1231 | ||
@@ -1225,21 +1235,21 @@ lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba, | |||
1225 | * NEXT STATE = PRLI_ISSUE | 1235 | * NEXT STATE = PRLI_ISSUE |
1226 | */ | 1236 | */ |
1227 | static uint32_t | 1237 | static uint32_t |
1228 | lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba, | 1238 | lpfc_rcv_prlo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1229 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1239 | void *arg, uint32_t evt) |
1230 | { | 1240 | { |
1231 | struct lpfc_iocbq *cmdiocb; | 1241 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1232 | 1242 | ||
1233 | cmdiocb = (struct lpfc_iocbq *) arg; | 1243 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
1234 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); | ||
1235 | return ndlp->nlp_state; | 1244 | return ndlp->nlp_state; |
1236 | } | 1245 | } |
1237 | 1246 | ||
1238 | static uint32_t | 1247 | static uint32_t |
1239 | lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | 1248 | lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1240 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1249 | void *arg, uint32_t evt) |
1241 | { | 1250 | { |
1242 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1251 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1252 | struct lpfc_hba *phba = vport->phba; | ||
1243 | IOCB_t *irsp; | 1253 | IOCB_t *irsp; |
1244 | PRLI *npr; | 1254 | PRLI *npr; |
1245 | 1255 | ||
@@ -1250,7 +1260,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1250 | irsp = &rspiocb->iocb; | 1260 | irsp = &rspiocb->iocb; |
1251 | if (irsp->ulpStatus) { | 1261 | if (irsp->ulpStatus) { |
1252 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | 1262 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; |
1253 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 1263 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1254 | return ndlp->nlp_state; | 1264 | return ndlp->nlp_state; |
1255 | } | 1265 | } |
1256 | 1266 | ||
@@ -1268,7 +1278,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1268 | } | 1278 | } |
1269 | 1279 | ||
1270 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | 1280 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; |
1271 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_MAPPED_NODE); | 1281 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE); |
1272 | return ndlp->nlp_state; | 1282 | return ndlp->nlp_state; |
1273 | } | 1283 | } |
1274 | 1284 | ||
@@ -1286,22 +1296,25 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1286 | * This routine is envoked when we a request to remove a nport we are in the | 1296 | * This routine is envoked when we a request to remove a nport we are in the |
1287 | * process of PRLIing. We should software abort outstanding prli, unreg | 1297 | * process of PRLIing. We should software abort outstanding prli, unreg |
1288 | * login, send a logout. We will change node state to UNUSED_NODE, put it | 1298 | * login, send a logout. We will change node state to UNUSED_NODE, put it |
1289 | * on plogi list so it can be freed when LOGO completes. | 1299 | * in plogi state so it can be freed when LOGO completes. |
1290 | * | 1300 | * |
1291 | */ | 1301 | */ |
1292 | static uint32_t | 1302 | static uint32_t |
1293 | lpfc_device_rm_prli_issue(struct lpfc_hba * phba, | 1303 | lpfc_device_rm_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1294 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1304 | void *arg, uint32_t evt) |
1295 | { | 1305 | { |
1296 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 1306 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1307 | |||
1308 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
1309 | spin_lock_irq(shost->host_lock); | ||
1297 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | 1310 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
1311 | spin_unlock_irq(shost->host_lock); | ||
1298 | return ndlp->nlp_state; | 1312 | return ndlp->nlp_state; |
1299 | } | 1313 | } else { |
1300 | else { | ||
1301 | /* software abort outstanding PLOGI */ | 1314 | /* software abort outstanding PLOGI */ |
1302 | lpfc_els_abort(phba, ndlp); | 1315 | lpfc_els_abort(vport->phba, ndlp); |
1303 | 1316 | ||
1304 | lpfc_drop_node(phba, ndlp); | 1317 | lpfc_drop_node(vport, ndlp); |
1305 | return NLP_STE_FREED_NODE; | 1318 | return NLP_STE_FREED_NODE; |
1306 | } | 1319 | } |
1307 | } | 1320 | } |
@@ -1324,261 +1337,247 @@ lpfc_device_rm_prli_issue(struct lpfc_hba * phba, | |||
1324 | * outstanding PRLI command, then free the node entry. | 1337 | * outstanding PRLI command, then free the node entry. |
1325 | */ | 1338 | */ |
1326 | static uint32_t | 1339 | static uint32_t |
1327 | lpfc_device_recov_prli_issue(struct lpfc_hba * phba, | 1340 | lpfc_device_recov_prli_issue(struct lpfc_vport *vport, |
1328 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1341 | struct lpfc_nodelist *ndlp, |
1342 | void *arg, | ||
1343 | uint32_t evt) | ||
1329 | { | 1344 | { |
1345 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1346 | struct lpfc_hba *phba = vport->phba; | ||
1347 | |||
1330 | /* software abort outstanding PRLI */ | 1348 | /* software abort outstanding PRLI */ |
1331 | lpfc_els_abort(phba, ndlp); | 1349 | lpfc_els_abort(phba, ndlp); |
1332 | 1350 | ||
1333 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | 1351 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; |
1334 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1352 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1335 | spin_lock_irq(phba->host->host_lock); | 1353 | spin_lock_irq(shost->host_lock); |
1336 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1354 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1337 | spin_unlock_irq(phba->host->host_lock); | 1355 | spin_unlock_irq(shost->host_lock); |
1338 | return ndlp->nlp_state; | 1356 | return ndlp->nlp_state; |
1339 | } | 1357 | } |
1340 | 1358 | ||
1341 | static uint32_t | 1359 | static uint32_t |
1342 | lpfc_rcv_plogi_unmap_node(struct lpfc_hba * phba, | 1360 | lpfc_rcv_plogi_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1343 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1361 | void *arg, uint32_t evt) |
1344 | { | 1362 | { |
1345 | struct lpfc_iocbq *cmdiocb; | 1363 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1346 | 1364 | ||
1347 | cmdiocb = (struct lpfc_iocbq *) arg; | 1365 | lpfc_rcv_plogi(vport, ndlp, cmdiocb); |
1348 | |||
1349 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | ||
1350 | return ndlp->nlp_state; | 1366 | return ndlp->nlp_state; |
1351 | } | 1367 | } |
1352 | 1368 | ||
1353 | static uint32_t | 1369 | static uint32_t |
1354 | lpfc_rcv_prli_unmap_node(struct lpfc_hba * phba, | 1370 | lpfc_rcv_prli_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1355 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1371 | void *arg, uint32_t evt) |
1356 | { | 1372 | { |
1357 | struct lpfc_iocbq *cmdiocb; | 1373 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1358 | 1374 | ||
1359 | cmdiocb = (struct lpfc_iocbq *) arg; | 1375 | lpfc_rcv_prli(vport, ndlp, cmdiocb); |
1360 | 1376 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); | |
1361 | lpfc_rcv_prli(phba, ndlp, cmdiocb); | ||
1362 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | ||
1363 | return ndlp->nlp_state; | 1377 | return ndlp->nlp_state; |
1364 | } | 1378 | } |
1365 | 1379 | ||
1366 | static uint32_t | 1380 | static uint32_t |
1367 | lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba, | 1381 | lpfc_rcv_logo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1368 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1382 | void *arg, uint32_t evt) |
1369 | { | 1383 | { |
1370 | struct lpfc_iocbq *cmdiocb; | 1384 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1371 | |||
1372 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1373 | 1385 | ||
1374 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 1386 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
1375 | return ndlp->nlp_state; | 1387 | return ndlp->nlp_state; |
1376 | } | 1388 | } |
1377 | 1389 | ||
1378 | static uint32_t | 1390 | static uint32_t |
1379 | lpfc_rcv_padisc_unmap_node(struct lpfc_hba * phba, | 1391 | lpfc_rcv_padisc_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1380 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1392 | void *arg, uint32_t evt) |
1381 | { | 1393 | { |
1382 | struct lpfc_iocbq *cmdiocb; | 1394 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1383 | |||
1384 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1385 | 1395 | ||
1386 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1396 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
1387 | return ndlp->nlp_state; | 1397 | return ndlp->nlp_state; |
1388 | } | 1398 | } |
1389 | 1399 | ||
1390 | static uint32_t | 1400 | static uint32_t |
1391 | lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba, | 1401 | lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1392 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1402 | void *arg, uint32_t evt) |
1393 | { | 1403 | { |
1394 | struct lpfc_iocbq *cmdiocb; | 1404 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1395 | 1405 | ||
1396 | cmdiocb = (struct lpfc_iocbq *) arg; | 1406 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
1397 | |||
1398 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); | ||
1399 | return ndlp->nlp_state; | 1407 | return ndlp->nlp_state; |
1400 | } | 1408 | } |
1401 | 1409 | ||
1402 | static uint32_t | 1410 | static uint32_t |
1403 | lpfc_device_recov_unmap_node(struct lpfc_hba * phba, | 1411 | lpfc_device_recov_unmap_node(struct lpfc_vport *vport, |
1404 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1412 | struct lpfc_nodelist *ndlp, |
1413 | void *arg, | ||
1414 | uint32_t evt) | ||
1405 | { | 1415 | { |
1416 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1417 | |||
1406 | ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; | 1418 | ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; |
1407 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1419 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1420 | spin_lock_irq(shost->host_lock); | ||
1408 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1421 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1409 | lpfc_disc_set_adisc(phba, ndlp); | 1422 | spin_unlock_irq(shost->host_lock); |
1423 | lpfc_disc_set_adisc(vport, ndlp); | ||
1410 | 1424 | ||
1411 | return ndlp->nlp_state; | 1425 | return ndlp->nlp_state; |
1412 | } | 1426 | } |
1413 | 1427 | ||
1414 | static uint32_t | 1428 | static uint32_t |
1415 | lpfc_rcv_plogi_mapped_node(struct lpfc_hba * phba, | 1429 | lpfc_rcv_plogi_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1416 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1430 | void *arg, uint32_t evt) |
1417 | { | 1431 | { |
1418 | struct lpfc_iocbq *cmdiocb; | 1432 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1419 | 1433 | ||
1420 | cmdiocb = (struct lpfc_iocbq *) arg; | 1434 | lpfc_rcv_plogi(vport, ndlp, cmdiocb); |
1421 | |||
1422 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | ||
1423 | return ndlp->nlp_state; | 1435 | return ndlp->nlp_state; |
1424 | } | 1436 | } |
1425 | 1437 | ||
1426 | static uint32_t | 1438 | static uint32_t |
1427 | lpfc_rcv_prli_mapped_node(struct lpfc_hba * phba, | 1439 | lpfc_rcv_prli_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1428 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1440 | void *arg, uint32_t evt) |
1429 | { | 1441 | { |
1430 | struct lpfc_iocbq *cmdiocb; | 1442 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1431 | 1443 | ||
1432 | cmdiocb = (struct lpfc_iocbq *) arg; | 1444 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); |
1433 | |||
1434 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | ||
1435 | return ndlp->nlp_state; | 1445 | return ndlp->nlp_state; |
1436 | } | 1446 | } |
1437 | 1447 | ||
1438 | static uint32_t | 1448 | static uint32_t |
1439 | lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba, | 1449 | lpfc_rcv_logo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1440 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1450 | void *arg, uint32_t evt) |
1441 | { | 1451 | { |
1442 | struct lpfc_iocbq *cmdiocb; | 1452 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1443 | 1453 | ||
1444 | cmdiocb = (struct lpfc_iocbq *) arg; | 1454 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
1445 | |||
1446 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | ||
1447 | return ndlp->nlp_state; | 1455 | return ndlp->nlp_state; |
1448 | } | 1456 | } |
1449 | 1457 | ||
1450 | static uint32_t | 1458 | static uint32_t |
1451 | lpfc_rcv_padisc_mapped_node(struct lpfc_hba * phba, | 1459 | lpfc_rcv_padisc_mapped_node(struct lpfc_vport *vport, |
1452 | struct lpfc_nodelist * ndlp, void *arg, | 1460 | struct lpfc_nodelist *ndlp, |
1453 | uint32_t evt) | 1461 | void *arg, uint32_t evt) |
1454 | { | 1462 | { |
1455 | struct lpfc_iocbq *cmdiocb; | 1463 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1456 | |||
1457 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1458 | 1464 | ||
1459 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1465 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
1460 | return ndlp->nlp_state; | 1466 | return ndlp->nlp_state; |
1461 | } | 1467 | } |
1462 | 1468 | ||
1463 | static uint32_t | 1469 | static uint32_t |
1464 | lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba, | 1470 | lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1465 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1471 | void *arg, uint32_t evt) |
1466 | { | 1472 | { |
1467 | struct lpfc_iocbq *cmdiocb; | 1473 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1468 | 1474 | struct lpfc_hba *phba = vport->phba; | |
1469 | cmdiocb = (struct lpfc_iocbq *) arg; | 1475 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1470 | 1476 | ||
1471 | /* flush the target */ | 1477 | /* flush the target */ |
1472 | spin_lock_irq(phba->host->host_lock); | 1478 | spin_lock_irq(shost->host_lock); |
1473 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], | 1479 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], |
1474 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); | 1480 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); |
1475 | spin_unlock_irq(phba->host->host_lock); | 1481 | spin_unlock_irq(shost->host_lock); |
1476 | 1482 | ||
1477 | /* Treat like rcv logo */ | 1483 | /* Treat like rcv logo */ |
1478 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO); | 1484 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO); |
1479 | return ndlp->nlp_state; | 1485 | return ndlp->nlp_state; |
1480 | } | 1486 | } |
1481 | 1487 | ||
1482 | static uint32_t | 1488 | static uint32_t |
1483 | lpfc_device_recov_mapped_node(struct lpfc_hba * phba, | 1489 | lpfc_device_recov_mapped_node(struct lpfc_vport *vport, |
1484 | struct lpfc_nodelist * ndlp, void *arg, | 1490 | struct lpfc_nodelist *ndlp, |
1485 | uint32_t evt) | 1491 | void *arg, |
1492 | uint32_t evt) | ||
1486 | { | 1493 | { |
1494 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1495 | |||
1487 | ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE; | 1496 | ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE; |
1488 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1497 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1489 | spin_lock_irq(phba->host->host_lock); | 1498 | spin_lock_irq(shost->host_lock); |
1490 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1499 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1491 | spin_unlock_irq(phba->host->host_lock); | 1500 | spin_unlock_irq(shost->host_lock); |
1492 | lpfc_disc_set_adisc(phba, ndlp); | 1501 | lpfc_disc_set_adisc(vport, ndlp); |
1493 | return ndlp->nlp_state; | 1502 | return ndlp->nlp_state; |
1494 | } | 1503 | } |
1495 | 1504 | ||
1496 | static uint32_t | 1505 | static uint32_t |
1497 | lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba, | 1506 | lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1498 | struct lpfc_nodelist * ndlp, void *arg, | 1507 | void *arg, uint32_t evt) |
1499 | uint32_t evt) | ||
1500 | { | 1508 | { |
1501 | struct lpfc_iocbq *cmdiocb; | 1509 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1502 | 1510 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; | |
1503 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1504 | 1511 | ||
1505 | /* Ignore PLOGI if we have an outstanding LOGO */ | 1512 | /* Ignore PLOGI if we have an outstanding LOGO */ |
1506 | if (ndlp->nlp_flag & NLP_LOGO_SND) { | 1513 | if (ndlp->nlp_flag & NLP_LOGO_SND) { |
1507 | return ndlp->nlp_state; | 1514 | return ndlp->nlp_state; |
1508 | } | 1515 | } |
1509 | 1516 | ||
1510 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 1517 | if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) { |
1511 | spin_lock_irq(phba->host->host_lock); | 1518 | spin_lock_irq(shost->host_lock); |
1512 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1519 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1513 | spin_unlock_irq(phba->host->host_lock); | 1520 | spin_unlock_irq(shost->host_lock); |
1514 | return ndlp->nlp_state; | 1521 | return ndlp->nlp_state; |
1515 | } | 1522 | } |
1516 | 1523 | ||
1517 | /* send PLOGI immediately, move to PLOGI issue state */ | 1524 | /* send PLOGI immediately, move to PLOGI issue state */ |
1518 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1525 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1519 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1526 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1520 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 1527 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
1521 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 1528 | lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); |
1522 | } | 1529 | } |
1523 | 1530 | ||
1524 | return ndlp->nlp_state; | 1531 | return ndlp->nlp_state; |
1525 | } | 1532 | } |
1526 | 1533 | ||
1527 | static uint32_t | 1534 | static uint32_t |
1528 | lpfc_rcv_prli_npr_node(struct lpfc_hba * phba, | 1535 | lpfc_rcv_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1529 | struct lpfc_nodelist * ndlp, void *arg, | 1536 | void *arg, uint32_t evt) |
1530 | uint32_t evt) | ||
1531 | { | 1537 | { |
1532 | struct lpfc_iocbq *cmdiocb; | 1538 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1533 | struct ls_rjt stat; | 1539 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1534 | 1540 | struct ls_rjt stat; | |
1535 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1536 | 1541 | ||
1537 | memset(&stat, 0, sizeof (struct ls_rjt)); | 1542 | memset(&stat, 0, sizeof (struct ls_rjt)); |
1538 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 1543 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
1539 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; | 1544 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; |
1540 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 1545 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
1541 | 1546 | ||
1542 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1547 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1543 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1548 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
1544 | spin_lock_irq(phba->host->host_lock); | 1549 | spin_lock_irq(shost->host_lock); |
1545 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1550 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1546 | spin_unlock_irq(phba->host->host_lock); | ||
1547 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1551 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1548 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); | 1552 | spin_unlock_irq(shost->host_lock); |
1549 | lpfc_issue_els_adisc(phba, ndlp, 0); | 1553 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); |
1554 | lpfc_issue_els_adisc(vport, ndlp, 0); | ||
1550 | } else { | 1555 | } else { |
1551 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1556 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1552 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 1557 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
1553 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 1558 | lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); |
1554 | } | 1559 | } |
1555 | } | 1560 | } |
1556 | return ndlp->nlp_state; | 1561 | return ndlp->nlp_state; |
1557 | } | 1562 | } |
1558 | 1563 | ||
1559 | static uint32_t | 1564 | static uint32_t |
1560 | lpfc_rcv_logo_npr_node(struct lpfc_hba * phba, | 1565 | lpfc_rcv_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1561 | struct lpfc_nodelist * ndlp, void *arg, | 1566 | void *arg, uint32_t evt) |
1562 | uint32_t evt) | ||
1563 | { | 1567 | { |
1564 | struct lpfc_iocbq *cmdiocb; | 1568 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1565 | |||
1566 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1567 | 1569 | ||
1568 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 1570 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
1569 | return ndlp->nlp_state; | 1571 | return ndlp->nlp_state; |
1570 | } | 1572 | } |
1571 | 1573 | ||
1572 | static uint32_t | 1574 | static uint32_t |
1573 | lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, | 1575 | lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1574 | struct lpfc_nodelist * ndlp, void *arg, | 1576 | void *arg, uint32_t evt) |
1575 | uint32_t evt) | ||
1576 | { | 1577 | { |
1577 | struct lpfc_iocbq *cmdiocb; | 1578 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1578 | |||
1579 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1580 | 1579 | ||
1581 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1580 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
1582 | 1581 | ||
1583 | /* | 1582 | /* |
1584 | * Do not start discovery if discovery is about to start | 1583 | * Do not start discovery if discovery is about to start |
@@ -1586,53 +1585,51 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, | |||
1586 | * here will affect the counting of discovery threads. | 1585 | * here will affect the counting of discovery threads. |
1587 | */ | 1586 | */ |
1588 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO) && | 1587 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO) && |
1589 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC)){ | 1588 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC)){ |
1590 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1589 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
1591 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1590 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1592 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); | 1591 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); |
1593 | lpfc_issue_els_adisc(phba, ndlp, 0); | 1592 | lpfc_issue_els_adisc(vport, ndlp, 0); |
1594 | } else { | 1593 | } else { |
1595 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1594 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1596 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 1595 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
1597 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 1596 | lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); |
1598 | } | 1597 | } |
1599 | } | 1598 | } |
1600 | return ndlp->nlp_state; | 1599 | return ndlp->nlp_state; |
1601 | } | 1600 | } |
1602 | 1601 | ||
1603 | static uint32_t | 1602 | static uint32_t |
1604 | lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba, | 1603 | lpfc_rcv_prlo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1605 | struct lpfc_nodelist * ndlp, void *arg, | 1604 | void *arg, uint32_t evt) |
1606 | uint32_t evt) | ||
1607 | { | 1605 | { |
1608 | struct lpfc_iocbq *cmdiocb; | 1606 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1607 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; | ||
1609 | 1608 | ||
1610 | cmdiocb = (struct lpfc_iocbq *) arg; | 1609 | spin_lock_irq(shost->host_lock); |
1611 | |||
1612 | spin_lock_irq(phba->host->host_lock); | ||
1613 | ndlp->nlp_flag |= NLP_LOGO_ACC; | 1610 | ndlp->nlp_flag |= NLP_LOGO_ACC; |
1614 | spin_unlock_irq(phba->host->host_lock); | 1611 | spin_unlock_irq(shost->host_lock); |
1615 | 1612 | ||
1616 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1613 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
1617 | 1614 | ||
1618 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1615 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) { |
1619 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 1616 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
1620 | spin_lock_irq(phba->host->host_lock); | 1617 | spin_lock_irq(shost->host_lock); |
1621 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1618 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1622 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1619 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1623 | spin_unlock_irq(phba->host->host_lock); | 1620 | spin_unlock_irq(shost->host_lock); |
1624 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 1621 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
1625 | } else { | 1622 | } else { |
1626 | spin_lock_irq(phba->host->host_lock); | 1623 | spin_lock_irq(shost->host_lock); |
1627 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1624 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1628 | spin_unlock_irq(phba->host->host_lock); | 1625 | spin_unlock_irq(shost->host_lock); |
1629 | } | 1626 | } |
1630 | return ndlp->nlp_state; | 1627 | return ndlp->nlp_state; |
1631 | } | 1628 | } |
1632 | 1629 | ||
1633 | static uint32_t | 1630 | static uint32_t |
1634 | lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba, | 1631 | lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1635 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1632 | void *arg, uint32_t evt) |
1636 | { | 1633 | { |
1637 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1634 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1638 | IOCB_t *irsp; | 1635 | IOCB_t *irsp; |
@@ -1642,15 +1639,15 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba, | |||
1642 | 1639 | ||
1643 | irsp = &rspiocb->iocb; | 1640 | irsp = &rspiocb->iocb; |
1644 | if (irsp->ulpStatus) { | 1641 | if (irsp->ulpStatus) { |
1645 | lpfc_drop_node(phba, ndlp); | 1642 | lpfc_drop_node(vport, ndlp); |
1646 | return NLP_STE_FREED_NODE; | 1643 | return NLP_STE_FREED_NODE; |
1647 | } | 1644 | } |
1648 | return ndlp->nlp_state; | 1645 | return ndlp->nlp_state; |
1649 | } | 1646 | } |
1650 | 1647 | ||
1651 | static uint32_t | 1648 | static uint32_t |
1652 | lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba, | 1649 | lpfc_cmpl_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1653 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1650 | void *arg, uint32_t evt) |
1654 | { | 1651 | { |
1655 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1652 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1656 | IOCB_t *irsp; | 1653 | IOCB_t *irsp; |
@@ -1660,25 +1657,24 @@ lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba, | |||
1660 | 1657 | ||
1661 | irsp = &rspiocb->iocb; | 1658 | irsp = &rspiocb->iocb; |
1662 | if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { | 1659 | if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { |
1663 | lpfc_drop_node(phba, ndlp); | 1660 | lpfc_drop_node(vport, ndlp); |
1664 | return NLP_STE_FREED_NODE; | 1661 | return NLP_STE_FREED_NODE; |
1665 | } | 1662 | } |
1666 | return ndlp->nlp_state; | 1663 | return ndlp->nlp_state; |
1667 | } | 1664 | } |
1668 | 1665 | ||
1669 | static uint32_t | 1666 | static uint32_t |
1670 | lpfc_cmpl_logo_npr_node(struct lpfc_hba * phba, | 1667 | lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1671 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1668 | void *arg, uint32_t evt) |
1672 | { | 1669 | { |
1673 | lpfc_unreg_rpi(phba, ndlp); | 1670 | lpfc_unreg_rpi(vport, ndlp); |
1674 | /* This routine does nothing, just return the current state */ | 1671 | /* This routine does nothing, just return the current state */ |
1675 | return ndlp->nlp_state; | 1672 | return ndlp->nlp_state; |
1676 | } | 1673 | } |
1677 | 1674 | ||
1678 | static uint32_t | 1675 | static uint32_t |
1679 | lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba, | 1676 | lpfc_cmpl_adisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1680 | struct lpfc_nodelist * ndlp, void *arg, | 1677 | void *arg, uint32_t evt) |
1681 | uint32_t evt) | ||
1682 | { | 1678 | { |
1683 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1679 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1684 | IOCB_t *irsp; | 1680 | IOCB_t *irsp; |
@@ -1688,28 +1684,25 @@ lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba, | |||
1688 | 1684 | ||
1689 | irsp = &rspiocb->iocb; | 1685 | irsp = &rspiocb->iocb; |
1690 | if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { | 1686 | if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { |
1691 | lpfc_drop_node(phba, ndlp); | 1687 | lpfc_drop_node(vport, ndlp); |
1692 | return NLP_STE_FREED_NODE; | 1688 | return NLP_STE_FREED_NODE; |
1693 | } | 1689 | } |
1694 | return ndlp->nlp_state; | 1690 | return ndlp->nlp_state; |
1695 | } | 1691 | } |
1696 | 1692 | ||
1697 | static uint32_t | 1693 | static uint32_t |
1698 | lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, | 1694 | lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport, |
1699 | struct lpfc_nodelist * ndlp, void *arg, | 1695 | struct lpfc_nodelist *ndlp, |
1700 | uint32_t evt) | 1696 | void *arg, uint32_t evt) |
1701 | { | 1697 | { |
1702 | LPFC_MBOXQ_t *pmb; | 1698 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; |
1703 | MAILBOX_t *mb; | 1699 | MAILBOX_t *mb = &pmb->mb; |
1704 | |||
1705 | pmb = (LPFC_MBOXQ_t *) arg; | ||
1706 | mb = &pmb->mb; | ||
1707 | 1700 | ||
1708 | if (!mb->mbxStatus) | 1701 | if (!mb->mbxStatus) |
1709 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1702 | ndlp->nlp_rpi = mb->un.varWords[0]; |
1710 | else { | 1703 | else { |
1711 | if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { | 1704 | if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { |
1712 | lpfc_drop_node(phba, ndlp); | 1705 | lpfc_drop_node(vport, ndlp); |
1713 | return NLP_STE_FREED_NODE; | 1706 | return NLP_STE_FREED_NODE; |
1714 | } | 1707 | } |
1715 | } | 1708 | } |
@@ -1717,28 +1710,32 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, | |||
1717 | } | 1710 | } |
1718 | 1711 | ||
1719 | static uint32_t | 1712 | static uint32_t |
1720 | lpfc_device_rm_npr_node(struct lpfc_hba * phba, | 1713 | lpfc_device_rm_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1721 | struct lpfc_nodelist * ndlp, void *arg, | 1714 | void *arg, uint32_t evt) |
1722 | uint32_t evt) | ||
1723 | { | 1715 | { |
1716 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1717 | |||
1724 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 1718 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { |
1719 | spin_lock_irq(shost->host_lock); | ||
1725 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | 1720 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
1721 | spin_unlock_irq(shost->host_lock); | ||
1726 | return ndlp->nlp_state; | 1722 | return ndlp->nlp_state; |
1727 | } | 1723 | } |
1728 | lpfc_drop_node(phba, ndlp); | 1724 | lpfc_drop_node(vport, ndlp); |
1729 | return NLP_STE_FREED_NODE; | 1725 | return NLP_STE_FREED_NODE; |
1730 | } | 1726 | } |
1731 | 1727 | ||
1732 | static uint32_t | 1728 | static uint32_t |
1733 | lpfc_device_recov_npr_node(struct lpfc_hba * phba, | 1729 | lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1734 | struct lpfc_nodelist * ndlp, void *arg, | 1730 | void *arg, uint32_t evt) |
1735 | uint32_t evt) | ||
1736 | { | 1731 | { |
1737 | spin_lock_irq(phba->host->host_lock); | 1732 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1733 | |||
1734 | spin_lock_irq(shost->host_lock); | ||
1738 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1735 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1739 | spin_unlock_irq(phba->host->host_lock); | 1736 | spin_unlock_irq(shost->host_lock); |
1740 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 1737 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
1741 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1738 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1742 | } | 1739 | } |
1743 | return ndlp->nlp_state; | 1740 | return ndlp->nlp_state; |
1744 | } | 1741 | } |
@@ -1801,7 +1798,7 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba, | |||
1801 | */ | 1798 | */ |
1802 | 1799 | ||
1803 | static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | 1800 | static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) |
1804 | (struct lpfc_hba *, struct lpfc_nodelist *, void *, uint32_t) = { | 1801 | (struct lpfc_vport *, struct lpfc_nodelist *, void *, uint32_t) = { |
1805 | /* Action routine Event Current State */ | 1802 | /* Action routine Event Current State */ |
1806 | lpfc_rcv_plogi_unused_node, /* RCV_PLOGI UNUSED_NODE */ | 1803 | lpfc_rcv_plogi_unused_node, /* RCV_PLOGI UNUSED_NODE */ |
1807 | lpfc_rcv_els_unused_node, /* RCV_PRLI */ | 1804 | lpfc_rcv_els_unused_node, /* RCV_PRLI */ |
@@ -1917,11 +1914,12 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | |||
1917 | }; | 1914 | }; |
1918 | 1915 | ||
1919 | int | 1916 | int |
1920 | lpfc_disc_state_machine(struct lpfc_hba * phba, | 1917 | lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1921 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1918 | void *arg, uint32_t evt) |
1922 | { | 1919 | { |
1920 | struct lpfc_hba *phba = vport->phba; | ||
1923 | uint32_t cur_state, rc; | 1921 | uint32_t cur_state, rc; |
1924 | uint32_t(*func) (struct lpfc_hba *, struct lpfc_nodelist *, void *, | 1922 | uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *, |
1925 | uint32_t); | 1923 | uint32_t); |
1926 | 1924 | ||
1927 | lpfc_nlp_get(ndlp); | 1925 | lpfc_nlp_get(ndlp); |
@@ -1937,7 +1935,7 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, | |||
1937 | evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag); | 1935 | evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag); |
1938 | 1936 | ||
1939 | func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt]; | 1937 | func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt]; |
1940 | rc = (func) (phba, ndlp, arg, evt); | 1938 | rc = (func) (vport, ndlp, arg, evt); |
1941 | 1939 | ||
1942 | /* DSM out state <rc> on NPort <nlp_DID> */ | 1940 | /* DSM out state <rc> on NPort <nlp_DID> */ |
1943 | lpfc_printf_log(phba, | 1941 | lpfc_printf_log(phba, |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 9a12d05e99e..6db7ad83cc3 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #define LPFC_RESET_WAIT 2 | 41 | #define LPFC_RESET_WAIT 2 |
42 | #define LPFC_ABORT_WAIT 2 | 42 | #define LPFC_ABORT_WAIT 2 |
43 | 43 | ||
44 | |||
45 | /* | 44 | /* |
46 | * This routine allocates a scsi buffer, which contains all the necessary | 45 | * This routine allocates a scsi buffer, which contains all the necessary |
47 | * information needed to initiate a SCSI I/O. The non-DMAable buffer region | 46 | * information needed to initiate a SCSI I/O. The non-DMAable buffer region |
@@ -51,8 +50,9 @@ | |||
51 | * and the BPL BDE is setup in the IOCB. | 50 | * and the BPL BDE is setup in the IOCB. |
52 | */ | 51 | */ |
53 | static struct lpfc_scsi_buf * | 52 | static struct lpfc_scsi_buf * |
54 | lpfc_new_scsi_buf(struct lpfc_hba * phba) | 53 | lpfc_new_scsi_buf(struct lpfc_vport *vport) |
55 | { | 54 | { |
55 | struct lpfc_hba *phba = vport->phba; | ||
56 | struct lpfc_scsi_buf *psb; | 56 | struct lpfc_scsi_buf *psb; |
57 | struct ulp_bde64 *bpl; | 57 | struct ulp_bde64 *bpl; |
58 | IOCB_t *iocb; | 58 | IOCB_t *iocb; |
@@ -63,7 +63,6 @@ lpfc_new_scsi_buf(struct lpfc_hba * phba) | |||
63 | if (!psb) | 63 | if (!psb) |
64 | return NULL; | 64 | return NULL; |
65 | memset(psb, 0, sizeof (struct lpfc_scsi_buf)); | 65 | memset(psb, 0, sizeof (struct lpfc_scsi_buf)); |
66 | psb->scsi_hba = phba; | ||
67 | 66 | ||
68 | /* | 67 | /* |
69 | * Get memory from the pci pool to map the virt space to pci bus space | 68 | * Get memory from the pci pool to map the virt space to pci bus space |
@@ -292,12 +291,13 @@ lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) | |||
292 | } | 291 | } |
293 | 292 | ||
294 | static void | 293 | static void |
295 | lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_iocbq *rsp_iocb) | 294 | lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, |
295 | struct lpfc_iocbq *rsp_iocb) | ||
296 | { | 296 | { |
297 | struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; | 297 | struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; |
298 | struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd; | 298 | struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd; |
299 | struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp; | 299 | struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp; |
300 | struct lpfc_hba *phba = lpfc_cmd->scsi_hba; | 300 | struct lpfc_hba *phba = vport->phba; |
301 | uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm; | 301 | uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm; |
302 | uint32_t resp_info = fcprsp->rspStatus2; | 302 | uint32_t resp_info = fcprsp->rspStatus2; |
303 | uint32_t scsi_status = fcprsp->rspStatus3; | 303 | uint32_t scsi_status = fcprsp->rspStatus3; |
@@ -429,6 +429,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
429 | { | 429 | { |
430 | struct lpfc_scsi_buf *lpfc_cmd = | 430 | struct lpfc_scsi_buf *lpfc_cmd = |
431 | (struct lpfc_scsi_buf *) pIocbIn->context1; | 431 | (struct lpfc_scsi_buf *) pIocbIn->context1; |
432 | struct lpfc_vport *vport = pIocbIn->vport; | ||
432 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; | 433 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; |
433 | struct lpfc_nodelist *pnode = rdata->pnode; | 434 | struct lpfc_nodelist *pnode = rdata->pnode; |
434 | struct scsi_cmnd *cmd = lpfc_cmd->pCmd; | 435 | struct scsi_cmnd *cmd = lpfc_cmd->pCmd; |
@@ -457,7 +458,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
457 | switch (lpfc_cmd->status) { | 458 | switch (lpfc_cmd->status) { |
458 | case IOSTAT_FCP_RSP_ERROR: | 459 | case IOSTAT_FCP_RSP_ERROR: |
459 | /* Call FCP RSP handler to determine result */ | 460 | /* Call FCP RSP handler to determine result */ |
460 | lpfc_handle_fcp_err(lpfc_cmd,pIocbOut); | 461 | lpfc_handle_fcp_err(vport, lpfc_cmd, pIocbOut); |
461 | break; | 462 | break; |
462 | case IOSTAT_NPORT_BSY: | 463 | case IOSTAT_NPORT_BSY: |
463 | case IOSTAT_FABRIC_BSY: | 464 | case IOSTAT_FABRIC_BSY: |
@@ -534,7 +535,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
534 | tmp_sdev->queue_depth - 1); | 535 | tmp_sdev->queue_depth - 1); |
535 | } | 536 | } |
536 | /* | 537 | /* |
537 | * The queue depth cannot be lowered any more. | 538 | * The queue depth cannot be lowered any more. |
538 | * Modify the returned error code to store | 539 | * Modify the returned error code to store |
539 | * the final depth value set by | 540 | * the final depth value set by |
540 | * scsi_track_queue_full. | 541 | * scsi_track_queue_full. |
@@ -553,9 +554,10 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
553 | } | 554 | } |
554 | 555 | ||
555 | static void | 556 | static void |
556 | lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd, | 557 | lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, |
557 | struct lpfc_nodelist *pnode) | 558 | struct lpfc_nodelist *pnode) |
558 | { | 559 | { |
560 | struct lpfc_hba *phba = vport->phba; | ||
559 | struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd; | 561 | struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd; |
560 | struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; | 562 | struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; |
561 | IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; | 563 | IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; |
@@ -642,15 +644,15 @@ lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd, | |||
642 | piocbq->context1 = lpfc_cmd; | 644 | piocbq->context1 = lpfc_cmd; |
643 | piocbq->iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl; | 645 | piocbq->iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl; |
644 | piocbq->iocb.ulpTimeout = lpfc_cmd->timeout; | 646 | piocbq->iocb.ulpTimeout = lpfc_cmd->timeout; |
647 | piocbq->vport = vport; | ||
645 | } | 648 | } |
646 | 649 | ||
647 | static int | 650 | static int |
648 | lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | 651 | lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, |
649 | struct lpfc_scsi_buf *lpfc_cmd, | 652 | struct lpfc_scsi_buf *lpfc_cmd, |
650 | unsigned int lun, | 653 | unsigned int lun, |
651 | uint8_t task_mgmt_cmd) | 654 | uint8_t task_mgmt_cmd) |
652 | { | 655 | { |
653 | struct lpfc_sli *psli; | ||
654 | struct lpfc_iocbq *piocbq; | 656 | struct lpfc_iocbq *piocbq; |
655 | IOCB_t *piocb; | 657 | IOCB_t *piocb; |
656 | struct fcp_cmnd *fcp_cmnd; | 658 | struct fcp_cmnd *fcp_cmnd; |
@@ -661,8 +663,9 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
661 | return 0; | 663 | return 0; |
662 | } | 664 | } |
663 | 665 | ||
664 | psli = &phba->sli; | ||
665 | piocbq = &(lpfc_cmd->cur_iocbq); | 666 | piocbq = &(lpfc_cmd->cur_iocbq); |
667 | piocbq->vport = vport; | ||
668 | |||
666 | piocb = &piocbq->iocb; | 669 | piocb = &piocbq->iocb; |
667 | 670 | ||
668 | fcp_cmnd = lpfc_cmd->fcp_cmnd; | 671 | fcp_cmnd = lpfc_cmd->fcp_cmnd; |
@@ -688,7 +691,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
688 | piocb->ulpTimeout = lpfc_cmd->timeout; | 691 | piocb->ulpTimeout = lpfc_cmd->timeout; |
689 | } | 692 | } |
690 | 693 | ||
691 | return (1); | 694 | return 1; |
692 | } | 695 | } |
693 | 696 | ||
694 | static void | 697 | static void |
@@ -704,10 +707,11 @@ lpfc_tskmgmt_def_cmpl(struct lpfc_hba *phba, | |||
704 | } | 707 | } |
705 | 708 | ||
706 | static int | 709 | static int |
707 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, | 710 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport, |
708 | unsigned tgt_id, unsigned int lun, | 711 | unsigned tgt_id, unsigned int lun, |
709 | struct lpfc_rport_data *rdata) | 712 | struct lpfc_rport_data *rdata) |
710 | { | 713 | { |
714 | struct lpfc_hba *phba = vport->phba; | ||
711 | struct lpfc_iocbq *iocbq; | 715 | struct lpfc_iocbq *iocbq; |
712 | struct lpfc_iocbq *iocbqrsp; | 716 | struct lpfc_iocbq *iocbqrsp; |
713 | int ret; | 717 | int ret; |
@@ -716,12 +720,11 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, | |||
716 | return FAILED; | 720 | return FAILED; |
717 | 721 | ||
718 | lpfc_cmd->rdata = rdata; | 722 | lpfc_cmd->rdata = rdata; |
719 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, | 723 | ret = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun, |
720 | FCP_TARGET_RESET); | 724 | FCP_TARGET_RESET); |
721 | if (!ret) | 725 | if (!ret) |
722 | return FAILED; | 726 | return FAILED; |
723 | 727 | ||
724 | lpfc_cmd->scsi_hba = phba; | ||
725 | iocbq = &lpfc_cmd->cur_iocbq; | 728 | iocbq = &lpfc_cmd->cur_iocbq; |
726 | iocbqrsp = lpfc_sli_get_iocbq(phba); | 729 | iocbqrsp = lpfc_sli_get_iocbq(phba); |
727 | 730 | ||
@@ -758,7 +761,8 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, | |||
758 | const char * | 761 | const char * |
759 | lpfc_info(struct Scsi_Host *host) | 762 | lpfc_info(struct Scsi_Host *host) |
760 | { | 763 | { |
761 | struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata; | 764 | struct lpfc_vport *vport = (struct lpfc_vport *) host->hostdata; |
765 | struct lpfc_hba *phba = vport->phba; | ||
762 | int len; | 766 | int len; |
763 | static char lpfcinfobuf[384]; | 767 | static char lpfcinfobuf[384]; |
764 | 768 | ||
@@ -800,26 +804,22 @@ void lpfc_poll_start_timer(struct lpfc_hba * phba) | |||
800 | 804 | ||
801 | void lpfc_poll_timeout(unsigned long ptr) | 805 | void lpfc_poll_timeout(unsigned long ptr) |
802 | { | 806 | { |
803 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; | 807 | struct lpfc_hba *phba = (struct lpfc_hba *) ptr; |
804 | unsigned long iflag; | ||
805 | |||
806 | spin_lock_irqsave(phba->host->host_lock, iflag); | ||
807 | 808 | ||
808 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 809 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
809 | lpfc_sli_poll_fcp_ring (phba); | 810 | lpfc_sli_poll_fcp_ring (phba); |
810 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) | 811 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) |
811 | lpfc_poll_rearm_timer(phba); | 812 | lpfc_poll_rearm_timer(phba); |
812 | } | 813 | } |
813 | |||
814 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | ||
815 | } | 814 | } |
816 | 815 | ||
817 | static int | 816 | static int |
818 | lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | 817 | lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) |
819 | { | 818 | { |
820 | struct lpfc_hba *phba = | 819 | struct Scsi_Host *shost = cmnd->device->host; |
821 | (struct lpfc_hba *) cmnd->device->host->hostdata; | 820 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
822 | struct lpfc_sli *psli = &phba->sli; | 821 | struct lpfc_hba *phba = vport->phba; |
822 | struct lpfc_sli *psli = &phba->sli; | ||
823 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; | 823 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; |
824 | struct lpfc_nodelist *ndlp = rdata->pnode; | 824 | struct lpfc_nodelist *ndlp = rdata->pnode; |
825 | struct lpfc_scsi_buf *lpfc_cmd; | 825 | struct lpfc_scsi_buf *lpfc_cmd; |
@@ -862,7 +862,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
862 | if (err) | 862 | if (err) |
863 | goto out_host_busy_free_buf; | 863 | goto out_host_busy_free_buf; |
864 | 864 | ||
865 | lpfc_scsi_prep_cmnd(phba, lpfc_cmd, ndlp); | 865 | lpfc_scsi_prep_cmnd(vport, lpfc_cmd, ndlp); |
866 | 866 | ||
867 | err = lpfc_sli_issue_iocb(phba, &phba->sli.ring[psli->fcp_ring], | 867 | err = lpfc_sli_issue_iocb(phba, &phba->sli.ring[psli->fcp_ring], |
868 | &lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB); | 868 | &lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB); |
@@ -907,8 +907,9 @@ lpfc_block_error_handler(struct scsi_cmnd *cmnd) | |||
907 | static int | 907 | static int |
908 | lpfc_abort_handler(struct scsi_cmnd *cmnd) | 908 | lpfc_abort_handler(struct scsi_cmnd *cmnd) |
909 | { | 909 | { |
910 | struct Scsi_Host *shost = cmnd->device->host; | 910 | struct Scsi_Host *shost = cmnd->device->host; |
911 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; | 911 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
912 | struct lpfc_hba *phba = vport->phba; | ||
912 | struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring]; | 913 | struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring]; |
913 | struct lpfc_iocbq *iocb; | 914 | struct lpfc_iocbq *iocb; |
914 | struct lpfc_iocbq *abtsiocb; | 915 | struct lpfc_iocbq *abtsiocb; |
@@ -918,8 +919,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
918 | int ret = SUCCESS; | 919 | int ret = SUCCESS; |
919 | 920 | ||
920 | lpfc_block_error_handler(cmnd); | 921 | lpfc_block_error_handler(cmnd); |
921 | spin_lock_irq(shost->host_lock); | ||
922 | |||
923 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; | 922 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
924 | BUG_ON(!lpfc_cmd); | 923 | BUG_ON(!lpfc_cmd); |
925 | 924 | ||
@@ -956,12 +955,13 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
956 | 955 | ||
957 | icmd->ulpLe = 1; | 956 | icmd->ulpLe = 1; |
958 | icmd->ulpClass = cmd->ulpClass; | 957 | icmd->ulpClass = cmd->ulpClass; |
959 | if (phba->hba_state >= LPFC_LINK_UP) | 958 | if (lpfc_is_link_up(phba)) |
960 | icmd->ulpCommand = CMD_ABORT_XRI_CN; | 959 | icmd->ulpCommand = CMD_ABORT_XRI_CN; |
961 | else | 960 | else |
962 | icmd->ulpCommand = CMD_CLOSE_XRI_CN; | 961 | icmd->ulpCommand = CMD_CLOSE_XRI_CN; |
963 | 962 | ||
964 | abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; | 963 | abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; |
964 | abtsiocb->vport = vport; | ||
965 | if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == IOCB_ERROR) { | 965 | if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == IOCB_ERROR) { |
966 | lpfc_sli_release_iocbq(phba, abtsiocb); | 966 | lpfc_sli_release_iocbq(phba, abtsiocb); |
967 | ret = FAILED; | 967 | ret = FAILED; |
@@ -977,9 +977,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
977 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) | 977 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) |
978 | lpfc_sli_poll_fcp_ring (phba); | 978 | lpfc_sli_poll_fcp_ring (phba); |
979 | 979 | ||
980 | spin_unlock_irq(phba->host->host_lock); | 980 | schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ); |
981 | schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ); | ||
982 | spin_lock_irq(phba->host->host_lock); | ||
983 | if (++loop_count | 981 | if (++loop_count |
984 | > (2 * phba->cfg_devloss_tmo)/LPFC_ABORT_WAIT) | 982 | > (2 * phba->cfg_devloss_tmo)/LPFC_ABORT_WAIT) |
985 | break; | 983 | break; |
@@ -1002,16 +1000,15 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
1002 | phba->brd_no, ret, cmnd->device->id, | 1000 | phba->brd_no, ret, cmnd->device->id, |
1003 | cmnd->device->lun, cmnd->serial_number); | 1001 | cmnd->device->lun, cmnd->serial_number); |
1004 | 1002 | ||
1005 | spin_unlock_irq(shost->host_lock); | ||
1006 | |||
1007 | return ret; | 1003 | return ret; |
1008 | } | 1004 | } |
1009 | 1005 | ||
1010 | static int | 1006 | static int |
1011 | lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | 1007 | lpfc_device_reset_handler(struct scsi_cmnd *cmnd) |
1012 | { | 1008 | { |
1013 | struct Scsi_Host *shost = cmnd->device->host; | 1009 | struct Scsi_Host *shost = cmnd->device->host; |
1014 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; | 1010 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1011 | struct lpfc_hba *phba = vport->phba; | ||
1015 | struct lpfc_scsi_buf *lpfc_cmd; | 1012 | struct lpfc_scsi_buf *lpfc_cmd; |
1016 | struct lpfc_iocbq *iocbq, *iocbqrsp; | 1013 | struct lpfc_iocbq *iocbq, *iocbqrsp; |
1017 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; | 1014 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; |
@@ -1022,7 +1019,6 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
1022 | int cnt, loopcnt; | 1019 | int cnt, loopcnt; |
1023 | 1020 | ||
1024 | lpfc_block_error_handler(cmnd); | 1021 | lpfc_block_error_handler(cmnd); |
1025 | spin_lock_irq(shost->host_lock); | ||
1026 | loopcnt = 0; | 1022 | loopcnt = 0; |
1027 | /* | 1023 | /* |
1028 | * If target is not in a MAPPED state, delay the reset until | 1024 | * If target is not in a MAPPED state, delay the reset until |
@@ -1033,9 +1029,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
1033 | goto out; | 1029 | goto out; |
1034 | 1030 | ||
1035 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { | 1031 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { |
1036 | spin_unlock_irq(phba->host->host_lock); | ||
1037 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); | 1032 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); |
1038 | spin_lock_irq(phba->host->host_lock); | ||
1039 | loopcnt++; | 1033 | loopcnt++; |
1040 | rdata = cmnd->device->hostdata; | 1034 | rdata = cmnd->device->hostdata; |
1041 | if (!rdata || | 1035 | if (!rdata || |
@@ -1054,15 +1048,14 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
1054 | break; | 1048 | break; |
1055 | } | 1049 | } |
1056 | 1050 | ||
1057 | lpfc_cmd = lpfc_get_scsi_buf (phba); | 1051 | lpfc_cmd = lpfc_get_scsi_buf(phba); |
1058 | if (lpfc_cmd == NULL) | 1052 | if (lpfc_cmd == NULL) |
1059 | goto out; | 1053 | goto out; |
1060 | 1054 | ||
1061 | lpfc_cmd->timeout = 60; | 1055 | lpfc_cmd->timeout = 60; |
1062 | lpfc_cmd->scsi_hba = phba; | ||
1063 | lpfc_cmd->rdata = rdata; | 1056 | lpfc_cmd->rdata = rdata; |
1064 | 1057 | ||
1065 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun, | 1058 | ret = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, cmnd->device->lun, |
1066 | FCP_TARGET_RESET); | 1059 | FCP_TARGET_RESET); |
1067 | if (!ret) | 1060 | if (!ret) |
1068 | goto out_free_scsi_buf; | 1061 | goto out_free_scsi_buf; |
@@ -1110,10 +1103,8 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
1110 | cmnd->device->id, cmnd->device->lun, | 1103 | cmnd->device->id, cmnd->device->lun, |
1111 | 0, LPFC_CTX_LUN); | 1104 | 0, LPFC_CTX_LUN); |
1112 | loopcnt = 0; | 1105 | loopcnt = 0; |
1113 | while(cnt) { | 1106 | while (cnt) { |
1114 | spin_unlock_irq(phba->host->host_lock); | ||
1115 | schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); | 1107 | schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); |
1116 | spin_lock_irq(phba->host->host_lock); | ||
1117 | 1108 | ||
1118 | if (++loopcnt | 1109 | if (++loopcnt |
1119 | > (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT) | 1110 | > (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT) |
@@ -1143,15 +1134,15 @@ out_free_scsi_buf: | |||
1143 | ret, cmd_status, cmd_result); | 1134 | ret, cmd_status, cmd_result); |
1144 | 1135 | ||
1145 | out: | 1136 | out: |
1146 | spin_unlock_irq(shost->host_lock); | ||
1147 | return ret; | 1137 | return ret; |
1148 | } | 1138 | } |
1149 | 1139 | ||
1150 | static int | 1140 | static int |
1151 | lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) | 1141 | lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) |
1152 | { | 1142 | { |
1153 | struct Scsi_Host *shost = cmnd->device->host; | 1143 | struct Scsi_Host *shost = cmnd->device->host; |
1154 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; | 1144 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1145 | struct lpfc_hba *phba = vport->phba; | ||
1155 | struct lpfc_nodelist *ndlp = NULL; | 1146 | struct lpfc_nodelist *ndlp = NULL; |
1156 | int match; | 1147 | int match; |
1157 | int ret = FAILED, i, err_count = 0; | 1148 | int ret = FAILED, i, err_count = 0; |
@@ -1159,7 +1150,6 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
1159 | struct lpfc_scsi_buf * lpfc_cmd; | 1150 | struct lpfc_scsi_buf * lpfc_cmd; |
1160 | 1151 | ||
1161 | lpfc_block_error_handler(cmnd); | 1152 | lpfc_block_error_handler(cmnd); |
1162 | spin_lock_irq(shost->host_lock); | ||
1163 | 1153 | ||
1164 | lpfc_cmd = lpfc_get_scsi_buf(phba); | 1154 | lpfc_cmd = lpfc_get_scsi_buf(phba); |
1165 | if (lpfc_cmd == NULL) | 1155 | if (lpfc_cmd == NULL) |
@@ -1167,7 +1157,6 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
1167 | 1157 | ||
1168 | /* The lpfc_cmd storage is reused. Set all loop invariants. */ | 1158 | /* The lpfc_cmd storage is reused. Set all loop invariants. */ |
1169 | lpfc_cmd->timeout = 60; | 1159 | lpfc_cmd->timeout = 60; |
1170 | lpfc_cmd->scsi_hba = phba; | ||
1171 | 1160 | ||
1172 | /* | 1161 | /* |
1173 | * Since the driver manages a single bus device, reset all | 1162 | * Since the driver manages a single bus device, reset all |
@@ -1177,7 +1166,8 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
1177 | for (i = 0; i < LPFC_MAX_TARGET; i++) { | 1166 | for (i = 0; i < LPFC_MAX_TARGET; i++) { |
1178 | /* Search for mapped node by target ID */ | 1167 | /* Search for mapped node by target ID */ |
1179 | match = 0; | 1168 | match = 0; |
1180 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { | 1169 | spin_lock_irq(shost->host_lock); |
1170 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { | ||
1181 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && | 1171 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && |
1182 | i == ndlp->nlp_sid && | 1172 | i == ndlp->nlp_sid && |
1183 | ndlp->rport) { | 1173 | ndlp->rport) { |
@@ -1185,10 +1175,12 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
1185 | break; | 1175 | break; |
1186 | } | 1176 | } |
1187 | } | 1177 | } |
1178 | spin_unlock_irq(shost->host_lock); | ||
1188 | if (!match) | 1179 | if (!match) |
1189 | continue; | 1180 | continue; |
1190 | 1181 | ||
1191 | ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, i, cmnd->device->lun, | 1182 | ret = lpfc_scsi_tgt_reset(lpfc_cmd, vport, i, |
1183 | cmnd->device->lun, | ||
1192 | ndlp->rport->dd_data); | 1184 | ndlp->rport->dd_data); |
1193 | if (ret != SUCCESS) { | 1185 | if (ret != SUCCESS) { |
1194 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1186 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
@@ -1218,10 +1210,8 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
1218 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], | 1210 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], |
1219 | 0, 0, 0, LPFC_CTX_HOST); | 1211 | 0, 0, 0, LPFC_CTX_HOST); |
1220 | loopcnt = 0; | 1212 | loopcnt = 0; |
1221 | while(cnt) { | 1213 | while (cnt) { |
1222 | spin_unlock_irq(phba->host->host_lock); | ||
1223 | schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); | 1214 | schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); |
1224 | spin_lock_irq(phba->host->host_lock); | ||
1225 | 1215 | ||
1226 | if (++loopcnt | 1216 | if (++loopcnt |
1227 | > (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT) | 1217 | > (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT) |
@@ -1245,14 +1235,14 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
1245 | "%d:0714 SCSI layer issued Bus Reset Data: x%x\n", | 1235 | "%d:0714 SCSI layer issued Bus Reset Data: x%x\n", |
1246 | phba->brd_no, ret); | 1236 | phba->brd_no, ret); |
1247 | out: | 1237 | out: |
1248 | spin_unlock_irq(shost->host_lock); | ||
1249 | return ret; | 1238 | return ret; |
1250 | } | 1239 | } |
1251 | 1240 | ||
1252 | static int | 1241 | static int |
1253 | lpfc_slave_alloc(struct scsi_device *sdev) | 1242 | lpfc_slave_alloc(struct scsi_device *sdev) |
1254 | { | 1243 | { |
1255 | struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata; | 1244 | struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata; |
1245 | struct lpfc_hba *phba = vport->phba; | ||
1256 | struct lpfc_scsi_buf *scsi_buf = NULL; | 1246 | struct lpfc_scsi_buf *scsi_buf = NULL; |
1257 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); | 1247 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); |
1258 | uint32_t total = 0, i; | 1248 | uint32_t total = 0, i; |
@@ -1289,7 +1279,7 @@ lpfc_slave_alloc(struct scsi_device *sdev) | |||
1289 | } | 1279 | } |
1290 | 1280 | ||
1291 | for (i = 0; i < num_to_alloc; i++) { | 1281 | for (i = 0; i < num_to_alloc; i++) { |
1292 | scsi_buf = lpfc_new_scsi_buf(phba); | 1282 | scsi_buf = lpfc_new_scsi_buf(vport); |
1293 | if (!scsi_buf) { | 1283 | if (!scsi_buf) { |
1294 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1284 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
1295 | "%d:0706 Failed to allocate command " | 1285 | "%d:0706 Failed to allocate command " |
@@ -1308,8 +1298,9 @@ lpfc_slave_alloc(struct scsi_device *sdev) | |||
1308 | static int | 1298 | static int |
1309 | lpfc_slave_configure(struct scsi_device *sdev) | 1299 | lpfc_slave_configure(struct scsi_device *sdev) |
1310 | { | 1300 | { |
1311 | struct lpfc_hba *phba = (struct lpfc_hba *) sdev->host->hostdata; | 1301 | struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata; |
1312 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); | 1302 | struct lpfc_hba *phba = vport->phba; |
1303 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); | ||
1313 | 1304 | ||
1314 | if (sdev->tagged_supported) | 1305 | if (sdev->tagged_supported) |
1315 | scsi_activate_tcq(sdev, phba->cfg_lun_queue_depth); | 1306 | scsi_activate_tcq(sdev, phba->cfg_lun_queue_depth); |
@@ -1357,6 +1348,6 @@ struct scsi_host_template lpfc_template = { | |||
1357 | .sg_tablesize = LPFC_SG_SEG_CNT, | 1348 | .sg_tablesize = LPFC_SG_SEG_CNT, |
1358 | .cmd_per_lun = LPFC_CMD_PER_LUN, | 1349 | .cmd_per_lun = LPFC_CMD_PER_LUN, |
1359 | .use_clustering = ENABLE_CLUSTERING, | 1350 | .use_clustering = ENABLE_CLUSTERING, |
1360 | .shost_attrs = lpfc_host_attrs, | 1351 | .shost_attrs = lpfc_hba_attrs, |
1361 | .max_sectors = 0xFFFF, | 1352 | .max_sectors = 0xFFFF, |
1362 | }; | 1353 | }; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index cdcd2535803..31787bb6d53 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -110,7 +110,6 @@ struct fcp_cmnd { | |||
110 | struct lpfc_scsi_buf { | 110 | struct lpfc_scsi_buf { |
111 | struct list_head list; | 111 | struct list_head list; |
112 | struct scsi_cmnd *pCmd; | 112 | struct scsi_cmnd *pCmd; |
113 | struct lpfc_hba *scsi_hba; | ||
114 | struct lpfc_rport_data *rdata; | 113 | struct lpfc_rport_data *rdata; |
115 | 114 | ||
116 | uint32_t timeout; | 115 | uint32_t timeout; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index a1e721459e2..1edac15eed4 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -52,9 +52,9 @@ | |||
52 | "Data: x%x x%x x%x\n", \ | 52 | "Data: x%x x%x x%x\n", \ |
53 | phba->brd_no, \ | 53 | phba->brd_no, \ |
54 | mb->mbxCommand, \ | 54 | mb->mbxCommand, \ |
55 | phba->hba_state, \ | 55 | phba->pport->port_state, \ |
56 | psli->sli_flag, \ | 56 | psli->sli_flag, \ |
57 | flag); | 57 | flag) |
58 | 58 | ||
59 | 59 | ||
60 | /* There are only four IOCB completion types. */ | 60 | /* There are only four IOCB completion types. */ |
@@ -65,8 +65,8 @@ typedef enum _lpfc_iocb_type { | |||
65 | LPFC_ABORT_IOCB | 65 | LPFC_ABORT_IOCB |
66 | } lpfc_iocb_type; | 66 | } lpfc_iocb_type; |
67 | 67 | ||
68 | struct lpfc_iocbq * | 68 | static struct lpfc_iocbq * |
69 | lpfc_sli_get_iocbq(struct lpfc_hba * phba) | 69 | __lpfc_sli_get_iocbq(struct lpfc_hba *phba) |
70 | { | 70 | { |
71 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | 71 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; |
72 | struct lpfc_iocbq * iocbq = NULL; | 72 | struct lpfc_iocbq * iocbq = NULL; |
@@ -75,10 +75,22 @@ lpfc_sli_get_iocbq(struct lpfc_hba * phba) | |||
75 | return iocbq; | 75 | return iocbq; |
76 | } | 76 | } |
77 | 77 | ||
78 | struct lpfc_iocbq * | ||
79 | lpfc_sli_get_iocbq(struct lpfc_hba *phba) | ||
80 | { | ||
81 | struct lpfc_iocbq * iocbq = NULL; | ||
82 | unsigned long iflags; | ||
83 | |||
84 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
85 | iocbq = __lpfc_sli_get_iocbq(phba); | ||
86 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
87 | return iocbq; | ||
88 | } | ||
89 | |||
78 | void | 90 | void |
79 | lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) | 91 | __lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) |
80 | { | 92 | { |
81 | size_t start_clean = (size_t)(&((struct lpfc_iocbq *)NULL)->iocb); | 93 | size_t start_clean = offsetof(struct lpfc_iocbq, iocb); |
82 | 94 | ||
83 | /* | 95 | /* |
84 | * Clean all volatile data fields, preserve iotag and node struct. | 96 | * Clean all volatile data fields, preserve iotag and node struct. |
@@ -87,6 +99,19 @@ lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) | |||
87 | list_add_tail(&iocbq->list, &phba->lpfc_iocb_list); | 99 | list_add_tail(&iocbq->list, &phba->lpfc_iocb_list); |
88 | } | 100 | } |
89 | 101 | ||
102 | void | ||
103 | lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) | ||
104 | { | ||
105 | unsigned long iflags; | ||
106 | |||
107 | /* | ||
108 | * Clean all volatile data fields, preserve iotag and node struct. | ||
109 | */ | ||
110 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
111 | __lpfc_sli_release_iocbq(phba, iocbq); | ||
112 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
113 | } | ||
114 | |||
90 | /* | 115 | /* |
91 | * Translate the iocb command to an iocb command type used to decide the final | 116 | * Translate the iocb command to an iocb command type used to decide the final |
92 | * disposition of each completed IOCB. | 117 | * disposition of each completed IOCB. |
@@ -166,14 +191,14 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) | |||
166 | } | 191 | } |
167 | 192 | ||
168 | static int | 193 | static int |
169 | lpfc_sli_ring_map(struct lpfc_hba * phba, LPFC_MBOXQ_t *pmb) | 194 | lpfc_sli_ring_map(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
170 | { | 195 | { |
171 | struct lpfc_sli *psli = &phba->sli; | 196 | struct lpfc_sli *psli = &phba->sli; |
172 | MAILBOX_t *pmbox = &pmb->mb; | 197 | MAILBOX_t *pmbox = &pmb->mb; |
173 | int i, rc; | 198 | int i, rc; |
174 | 199 | ||
175 | for (i = 0; i < psli->num_rings; i++) { | 200 | for (i = 0; i < psli->num_rings; i++) { |
176 | phba->hba_state = LPFC_INIT_MBX_CMDS; | 201 | phba->link_state = LPFC_INIT_MBX_CMDS; |
177 | lpfc_config_ring(phba, i, pmb); | 202 | lpfc_config_ring(phba, i, pmb); |
178 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | 203 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); |
179 | if (rc != MBX_SUCCESS) { | 204 | if (rc != MBX_SUCCESS) { |
@@ -187,7 +212,7 @@ lpfc_sli_ring_map(struct lpfc_hba * phba, LPFC_MBOXQ_t *pmb) | |||
187 | pmbox->mbxCommand, | 212 | pmbox->mbxCommand, |
188 | pmbox->mbxStatus, | 213 | pmbox->mbxStatus, |
189 | i); | 214 | i); |
190 | phba->hba_state = LPFC_HBA_ERROR; | 215 | phba->link_state = LPFC_HBA_ERROR; |
191 | return -ENXIO; | 216 | return -ENXIO; |
192 | } | 217 | } |
193 | } | 218 | } |
@@ -195,20 +220,20 @@ lpfc_sli_ring_map(struct lpfc_hba * phba, LPFC_MBOXQ_t *pmb) | |||
195 | } | 220 | } |
196 | 221 | ||
197 | static int | 222 | static int |
198 | lpfc_sli_ringtxcmpl_put(struct lpfc_hba * phba, | 223 | lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
199 | struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocb) | 224 | struct lpfc_iocbq *piocb) |
200 | { | 225 | { |
201 | list_add_tail(&piocb->list, &pring->txcmplq); | 226 | list_add_tail(&piocb->list, &pring->txcmplq); |
202 | pring->txcmplq_cnt++; | 227 | pring->txcmplq_cnt++; |
203 | if (unlikely(pring->ringno == LPFC_ELS_RING)) | 228 | if (unlikely(pring->ringno == LPFC_ELS_RING)) |
204 | mod_timer(&phba->els_tmofunc, | 229 | mod_timer(&piocb->vport->els_tmofunc, |
205 | jiffies + HZ * (phba->fc_ratov << 1)); | 230 | jiffies + HZ * (phba->fc_ratov << 1)); |
206 | 231 | ||
207 | return (0); | 232 | return 0; |
208 | } | 233 | } |
209 | 234 | ||
210 | static struct lpfc_iocbq * | 235 | static struct lpfc_iocbq * |
211 | lpfc_sli_ringtx_get(struct lpfc_hba * phba, struct lpfc_sli_ring * pring) | 236 | lpfc_sli_ringtx_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) |
212 | { | 237 | { |
213 | struct list_head *dlp; | 238 | struct list_head *dlp; |
214 | struct lpfc_iocbq *cmd_iocb; | 239 | struct lpfc_iocbq *cmd_iocb; |
@@ -224,7 +249,7 @@ lpfc_sli_ringtx_get(struct lpfc_hba * phba, struct lpfc_sli_ring * pring) | |||
224 | */ | 249 | */ |
225 | pring->txq_cnt--; | 250 | pring->txq_cnt--; |
226 | } | 251 | } |
227 | return (cmd_iocb); | 252 | return cmd_iocb; |
228 | } | 253 | } |
229 | 254 | ||
230 | static IOCB_t * | 255 | static IOCB_t * |
@@ -249,7 +274,7 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
249 | phba->brd_no, pring->ringno, | 274 | phba->brd_no, pring->ringno, |
250 | pring->local_getidx, max_cmd_idx); | 275 | pring->local_getidx, max_cmd_idx); |
251 | 276 | ||
252 | phba->hba_state = LPFC_HBA_ERROR; | 277 | phba->link_state = LPFC_HBA_ERROR; |
253 | /* | 278 | /* |
254 | * All error attention handlers are posted to | 279 | * All error attention handlers are posted to |
255 | * worker thread | 280 | * worker thread |
@@ -272,33 +297,30 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
272 | } | 297 | } |
273 | 298 | ||
274 | uint16_t | 299 | uint16_t |
275 | lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) | 300 | lpfc_sli_next_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) |
276 | { | 301 | { |
277 | struct lpfc_iocbq ** new_arr; | 302 | struct lpfc_iocbq **new_arr; |
278 | struct lpfc_iocbq ** old_arr; | 303 | struct lpfc_iocbq **old_arr; |
279 | size_t new_len; | 304 | size_t new_len; |
280 | struct lpfc_sli *psli = &phba->sli; | 305 | struct lpfc_sli *psli = &phba->sli; |
281 | uint16_t iotag; | 306 | uint16_t iotag; |
282 | 307 | ||
283 | spin_lock_irq(phba->host->host_lock); | 308 | spin_lock_irq(&phba->hbalock); |
284 | iotag = psli->last_iotag; | 309 | iotag = psli->last_iotag; |
285 | if(++iotag < psli->iocbq_lookup_len) { | 310 | if(++iotag < psli->iocbq_lookup_len) { |
286 | psli->last_iotag = iotag; | 311 | psli->last_iotag = iotag; |
287 | psli->iocbq_lookup[iotag] = iocbq; | 312 | psli->iocbq_lookup[iotag] = iocbq; |
288 | spin_unlock_irq(phba->host->host_lock); | 313 | spin_unlock_irq(&phba->hbalock); |
289 | iocbq->iotag = iotag; | 314 | iocbq->iotag = iotag; |
290 | return iotag; | 315 | return iotag; |
291 | } | 316 | } else if (psli->iocbq_lookup_len < (0xffff |
292 | else if (psli->iocbq_lookup_len < (0xffff | ||
293 | - LPFC_IOCBQ_LOOKUP_INCREMENT)) { | 317 | - LPFC_IOCBQ_LOOKUP_INCREMENT)) { |
294 | new_len = psli->iocbq_lookup_len + LPFC_IOCBQ_LOOKUP_INCREMENT; | 318 | new_len = psli->iocbq_lookup_len + LPFC_IOCBQ_LOOKUP_INCREMENT; |
295 | spin_unlock_irq(phba->host->host_lock); | 319 | spin_unlock_irq(&phba->hbalock); |
296 | new_arr = kmalloc(new_len * sizeof (struct lpfc_iocbq *), | 320 | new_arr = kzalloc(new_len * sizeof (struct lpfc_iocbq *), |
297 | GFP_KERNEL); | 321 | GFP_KERNEL); |
298 | if (new_arr) { | 322 | if (new_arr) { |
299 | memset((char *)new_arr, 0, | 323 | spin_lock_irq(&phba->hbalock); |
300 | new_len * sizeof (struct lpfc_iocbq *)); | ||
301 | spin_lock_irq(phba->host->host_lock); | ||
302 | old_arr = psli->iocbq_lookup; | 324 | old_arr = psli->iocbq_lookup; |
303 | if (new_len <= psli->iocbq_lookup_len) { | 325 | if (new_len <= psli->iocbq_lookup_len) { |
304 | /* highly unprobable case */ | 326 | /* highly unprobable case */ |
@@ -307,11 +329,11 @@ lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) | |||
307 | if(++iotag < psli->iocbq_lookup_len) { | 329 | if(++iotag < psli->iocbq_lookup_len) { |
308 | psli->last_iotag = iotag; | 330 | psli->last_iotag = iotag; |
309 | psli->iocbq_lookup[iotag] = iocbq; | 331 | psli->iocbq_lookup[iotag] = iocbq; |
310 | spin_unlock_irq(phba->host->host_lock); | 332 | spin_unlock_irq(&phba->hbalock); |
311 | iocbq->iotag = iotag; | 333 | iocbq->iotag = iotag; |
312 | return iotag; | 334 | return iotag; |
313 | } | 335 | } |
314 | spin_unlock_irq(phba->host->host_lock); | 336 | spin_unlock_irq(&phba->hbalock); |
315 | return 0; | 337 | return 0; |
316 | } | 338 | } |
317 | if (psli->iocbq_lookup) | 339 | if (psli->iocbq_lookup) |
@@ -322,13 +344,13 @@ lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) | |||
322 | psli->iocbq_lookup_len = new_len; | 344 | psli->iocbq_lookup_len = new_len; |
323 | psli->last_iotag = iotag; | 345 | psli->last_iotag = iotag; |
324 | psli->iocbq_lookup[iotag] = iocbq; | 346 | psli->iocbq_lookup[iotag] = iocbq; |
325 | spin_unlock_irq(phba->host->host_lock); | 347 | spin_unlock_irq(&phba->hbalock); |
326 | iocbq->iotag = iotag; | 348 | iocbq->iotag = iotag; |
327 | kfree(old_arr); | 349 | kfree(old_arr); |
328 | return iotag; | 350 | return iotag; |
329 | } | 351 | } |
330 | } else | 352 | } else |
331 | spin_unlock_irq(phba->host->host_lock); | 353 | spin_unlock_irq(&phba->hbalock); |
332 | 354 | ||
333 | lpfc_printf_log(phba, KERN_ERR,LOG_SLI, | 355 | lpfc_printf_log(phba, KERN_ERR,LOG_SLI, |
334 | "%d:0318 Failed to allocate IOTAG.last IOTAG is %d\n", | 356 | "%d:0318 Failed to allocate IOTAG.last IOTAG is %d\n", |
@@ -361,7 +383,7 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
361 | if (nextiocb->iocb_cmpl) | 383 | if (nextiocb->iocb_cmpl) |
362 | lpfc_sli_ringtxcmpl_put(phba, pring, nextiocb); | 384 | lpfc_sli_ringtxcmpl_put(phba, pring, nextiocb); |
363 | else | 385 | else |
364 | lpfc_sli_release_iocbq(phba, nextiocb); | 386 | __lpfc_sli_release_iocbq(phba, nextiocb); |
365 | 387 | ||
366 | /* | 388 | /* |
367 | * Let the HBA know what IOCB slot will be the next one the | 389 | * Let the HBA know what IOCB slot will be the next one the |
@@ -373,8 +395,7 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
373 | } | 395 | } |
374 | 396 | ||
375 | static void | 397 | static void |
376 | lpfc_sli_update_full_ring(struct lpfc_hba * phba, | 398 | lpfc_sli_update_full_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) |
377 | struct lpfc_sli_ring *pring) | ||
378 | { | 399 | { |
379 | int ringno = pring->ringno; | 400 | int ringno = pring->ringno; |
380 | 401 | ||
@@ -393,8 +414,7 @@ lpfc_sli_update_full_ring(struct lpfc_hba * phba, | |||
393 | } | 414 | } |
394 | 415 | ||
395 | static void | 416 | static void |
396 | lpfc_sli_update_ring(struct lpfc_hba * phba, | 417 | lpfc_sli_update_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) |
397 | struct lpfc_sli_ring *pring) | ||
398 | { | 418 | { |
399 | int ringno = pring->ringno; | 419 | int ringno = pring->ringno; |
400 | 420 | ||
@@ -407,7 +427,7 @@ lpfc_sli_update_ring(struct lpfc_hba * phba, | |||
407 | } | 427 | } |
408 | 428 | ||
409 | static void | 429 | static void |
410 | lpfc_sli_resume_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring) | 430 | lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) |
411 | { | 431 | { |
412 | IOCB_t *iocb; | 432 | IOCB_t *iocb; |
413 | struct lpfc_iocbq *nextiocb; | 433 | struct lpfc_iocbq *nextiocb; |
@@ -420,7 +440,7 @@ lpfc_sli_resume_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring) | |||
420 | * (d) IOCB processing is not blocked by the outstanding mbox command. | 440 | * (d) IOCB processing is not blocked by the outstanding mbox command. |
421 | */ | 441 | */ |
422 | if (pring->txq_cnt && | 442 | if (pring->txq_cnt && |
423 | (phba->hba_state > LPFC_LINK_DOWN) && | 443 | lpfc_is_link_up(phba) && |
424 | (pring->ringno != phba->sli.fcp_ring || | 444 | (pring->ringno != phba->sli.fcp_ring || |
425 | phba->sli.sli_flag & LPFC_PROCESS_LA) && | 445 | phba->sli.sli_flag & LPFC_PROCESS_LA) && |
426 | !(pring->flag & LPFC_STOP_IOCB_MBX)) { | 446 | !(pring->flag & LPFC_STOP_IOCB_MBX)) { |
@@ -440,11 +460,13 @@ lpfc_sli_resume_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring) | |||
440 | 460 | ||
441 | /* lpfc_sli_turn_on_ring is only called by lpfc_sli_handle_mb_event below */ | 461 | /* lpfc_sli_turn_on_ring is only called by lpfc_sli_handle_mb_event below */ |
442 | static void | 462 | static void |
443 | lpfc_sli_turn_on_ring(struct lpfc_hba * phba, int ringno) | 463 | lpfc_sli_turn_on_ring(struct lpfc_hba *phba, int ringno) |
444 | { | 464 | { |
445 | struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[ringno]; | 465 | struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[ringno]; |
466 | unsigned long iflags; | ||
446 | 467 | ||
447 | /* If the ring is active, flag it */ | 468 | /* If the ring is active, flag it */ |
469 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
448 | if (phba->sli.ring[ringno].cmdringaddr) { | 470 | if (phba->sli.ring[ringno].cmdringaddr) { |
449 | if (phba->sli.ring[ringno].flag & LPFC_STOP_IOCB_MBX) { | 471 | if (phba->sli.ring[ringno].flag & LPFC_STOP_IOCB_MBX) { |
450 | phba->sli.ring[ringno].flag &= ~LPFC_STOP_IOCB_MBX; | 472 | phba->sli.ring[ringno].flag &= ~LPFC_STOP_IOCB_MBX; |
@@ -453,11 +475,10 @@ lpfc_sli_turn_on_ring(struct lpfc_hba * phba, int ringno) | |||
453 | */ | 475 | */ |
454 | phba->sli.ring[ringno].local_getidx | 476 | phba->sli.ring[ringno].local_getidx |
455 | = le32_to_cpu(pgp->cmdGetInx); | 477 | = le32_to_cpu(pgp->cmdGetInx); |
456 | spin_lock_irq(phba->host->host_lock); | ||
457 | lpfc_sli_resume_iocb(phba, &phba->sli.ring[ringno]); | 478 | lpfc_sli_resume_iocb(phba, &phba->sli.ring[ringno]); |
458 | spin_unlock_irq(phba->host->host_lock); | ||
459 | } | 479 | } |
460 | } | 480 | } |
481 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
461 | } | 482 | } |
462 | 483 | ||
463 | static int | 484 | static int |
@@ -517,10 +538,10 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
517 | ret = MBX_SHUTDOWN; | 538 | ret = MBX_SHUTDOWN; |
518 | break; | 539 | break; |
519 | } | 540 | } |
520 | return (ret); | 541 | return ret; |
521 | } | 542 | } |
522 | static void | 543 | static void |
523 | lpfc_sli_wake_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) | 544 | lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) |
524 | { | 545 | { |
525 | wait_queue_head_t *pdone_q; | 546 | wait_queue_head_t *pdone_q; |
526 | 547 | ||
@@ -536,7 +557,7 @@ lpfc_sli_wake_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) | |||
536 | } | 557 | } |
537 | 558 | ||
538 | void | 559 | void |
539 | lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 560 | lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
540 | { | 561 | { |
541 | struct lpfc_dmabuf *mp; | 562 | struct lpfc_dmabuf *mp; |
542 | uint16_t rpi; | 563 | uint16_t rpi; |
@@ -553,9 +574,9 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
553 | * If a REG_LOGIN succeeded after node is destroyed or node | 574 | * If a REG_LOGIN succeeded after node is destroyed or node |
554 | * is in re-discovery driver need to cleanup the RPI. | 575 | * is in re-discovery driver need to cleanup the RPI. |
555 | */ | 576 | */ |
556 | if (!(phba->fc_flag & FC_UNLOADING) && | 577 | if (!(phba->pport->load_flag & FC_UNLOADING) && |
557 | (pmb->mb.mbxCommand == MBX_REG_LOGIN64) && | 578 | pmb->mb.mbxCommand == MBX_REG_LOGIN64 && |
558 | (!pmb->mb.mbxStatus)) { | 579 | !pmb->mb.mbxStatus) { |
559 | 580 | ||
560 | rpi = pmb->mb.un.varWords[0]; | 581 | rpi = pmb->mb.un.varWords[0]; |
561 | lpfc_unreg_login(phba, rpi, pmb); | 582 | lpfc_unreg_login(phba, rpi, pmb); |
@@ -565,24 +586,22 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
565 | return; | 586 | return; |
566 | } | 587 | } |
567 | 588 | ||
568 | mempool_free( pmb, phba->mbox_mem_pool); | 589 | mempool_free(pmb, phba->mbox_mem_pool); |
569 | return; | 590 | return; |
570 | } | 591 | } |
571 | 592 | ||
572 | int | 593 | int |
573 | lpfc_sli_handle_mb_event(struct lpfc_hba * phba) | 594 | lpfc_sli_handle_mb_event(struct lpfc_hba *phba) |
574 | { | 595 | { |
575 | MAILBOX_t *mbox; | 596 | MAILBOX_t *mbox, *pmbox; |
576 | MAILBOX_t *pmbox; | ||
577 | LPFC_MBOXQ_t *pmb; | 597 | LPFC_MBOXQ_t *pmb; |
578 | struct lpfc_sli *psli; | ||
579 | int i, rc; | 598 | int i, rc; |
580 | uint32_t process_next; | 599 | uint32_t process_next; |
600 | unsigned long iflags; | ||
581 | 601 | ||
582 | psli = &phba->sli; | ||
583 | /* We should only get here if we are in SLI2 mode */ | 602 | /* We should only get here if we are in SLI2 mode */ |
584 | if (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE)) { | 603 | if (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE)) { |
585 | return (1); | 604 | return 1; |
586 | } | 605 | } |
587 | 606 | ||
588 | phba->sli.slistat.mbox_event++; | 607 | phba->sli.slistat.mbox_event++; |
@@ -616,15 +635,18 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) | |||
616 | pmbox->mbxCommand, | 635 | pmbox->mbxCommand, |
617 | pmbox->mbxStatus); | 636 | pmbox->mbxStatus); |
618 | 637 | ||
619 | spin_lock_irq(phba->host->host_lock); | 638 | spin_lock_irq(&phba->hbalock); |
620 | phba->sli.sli_flag |= LPFC_SLI_MBOX_ACTIVE; | 639 | phba->sli.sli_flag |= LPFC_SLI_MBOX_ACTIVE; |
621 | spin_unlock_irq(phba->host->host_lock); | 640 | spin_unlock_irq(&phba->hbalock); |
622 | return (1); | 641 | return 1; |
623 | } | 642 | } |
624 | 643 | ||
625 | mbout: | 644 | mbout: |
626 | del_timer_sync(&phba->sli.mbox_tmo); | 645 | del_timer_sync(&phba->sli.mbox_tmo); |
627 | phba->work_hba_events &= ~WORKER_MBOX_TMO; | 646 | |
647 | spin_lock_irqsave(&phba->pport->work_port_lock, iflags); | ||
648 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; | ||
649 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags); | ||
628 | 650 | ||
629 | /* | 651 | /* |
630 | * It is a fatal error if unknown mbox command completion. | 652 | * It is a fatal error if unknown mbox command completion. |
@@ -639,10 +661,10 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) | |||
639 | "%d:0323 Unknown Mailbox command %x Cmpl\n", | 661 | "%d:0323 Unknown Mailbox command %x Cmpl\n", |
640 | phba->brd_no, | 662 | phba->brd_no, |
641 | pmbox->mbxCommand); | 663 | pmbox->mbxCommand); |
642 | phba->hba_state = LPFC_HBA_ERROR; | 664 | phba->link_state = LPFC_HBA_ERROR; |
643 | phba->work_hs = HS_FFER3; | 665 | phba->work_hs = HS_FFER3; |
644 | lpfc_handle_eratt(phba); | 666 | lpfc_handle_eratt(phba); |
645 | return (0); | 667 | return 0; |
646 | } | 668 | } |
647 | 669 | ||
648 | phba->sli.mbox_active = NULL; | 670 | phba->sli.mbox_active = NULL; |
@@ -659,15 +681,15 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) | |||
659 | pmbox->mbxCommand, | 681 | pmbox->mbxCommand, |
660 | pmbox->mbxStatus, | 682 | pmbox->mbxStatus, |
661 | pmbox->un.varWords[0], | 683 | pmbox->un.varWords[0], |
662 | phba->hba_state); | 684 | phba->pport->port_state); |
663 | pmbox->mbxStatus = 0; | 685 | pmbox->mbxStatus = 0; |
664 | pmbox->mbxOwner = OWN_HOST; | 686 | pmbox->mbxOwner = OWN_HOST; |
665 | spin_lock_irq(phba->host->host_lock); | 687 | spin_lock_irq(&phba->hbalock); |
666 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 688 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
667 | spin_unlock_irq(phba->host->host_lock); | 689 | spin_unlock_irq(&phba->hbalock); |
668 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 690 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); |
669 | if (rc == MBX_SUCCESS) | 691 | if (rc == MBX_SUCCESS) |
670 | return (0); | 692 | return 0; |
671 | } | 693 | } |
672 | } | 694 | } |
673 | 695 | ||
@@ -699,12 +721,12 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) | |||
699 | 721 | ||
700 | do { | 722 | do { |
701 | process_next = 0; /* by default don't loop */ | 723 | process_next = 0; /* by default don't loop */ |
702 | spin_lock_irq(phba->host->host_lock); | 724 | spin_lock_irq(&phba->hbalock); |
703 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 725 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
704 | 726 | ||
705 | /* Process next mailbox command if there is one */ | 727 | /* Process next mailbox command if there is one */ |
706 | if ((pmb = lpfc_mbox_get(phba))) { | 728 | if ((pmb = lpfc_mbox_get(phba))) { |
707 | spin_unlock_irq(phba->host->host_lock); | 729 | spin_unlock_irq(&phba->hbalock); |
708 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 730 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); |
709 | if (rc == MBX_NOT_FINISHED) { | 731 | if (rc == MBX_NOT_FINISHED) { |
710 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; | 732 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; |
@@ -713,7 +735,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) | |||
713 | continue; /* loop back */ | 735 | continue; /* loop back */ |
714 | } | 736 | } |
715 | } else { | 737 | } else { |
716 | spin_unlock_irq(phba->host->host_lock); | 738 | spin_unlock_irq(&phba->hbalock); |
717 | /* Turn on IOCB processing */ | 739 | /* Turn on IOCB processing */ |
718 | for (i = 0; i < phba->sli.num_rings; i++) | 740 | for (i = 0; i < phba->sli.num_rings; i++) |
719 | lpfc_sli_turn_on_ring(phba, i); | 741 | lpfc_sli_turn_on_ring(phba, i); |
@@ -721,7 +743,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) | |||
721 | 743 | ||
722 | } while (process_next); | 744 | } while (process_next); |
723 | 745 | ||
724 | return (0); | 746 | return 0; |
725 | } | 747 | } |
726 | static int | 748 | static int |
727 | lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 749 | lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
@@ -795,9 +817,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
795 | } | 817 | } |
796 | 818 | ||
797 | static struct lpfc_iocbq * | 819 | static struct lpfc_iocbq * |
798 | lpfc_sli_iocbq_lookup(struct lpfc_hba * phba, | 820 | lpfc_sli_iocbq_lookup(struct lpfc_hba *phba, |
799 | struct lpfc_sli_ring * pring, | 821 | struct lpfc_sli_ring *pring, |
800 | struct lpfc_iocbq * prspiocb) | 822 | struct lpfc_iocbq *prspiocb) |
801 | { | 823 | { |
802 | struct lpfc_iocbq *cmd_iocb = NULL; | 824 | struct lpfc_iocbq *cmd_iocb = NULL; |
803 | uint16_t iotag; | 825 | uint16_t iotag; |
@@ -821,16 +843,18 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba * phba, | |||
821 | } | 843 | } |
822 | 844 | ||
823 | static int | 845 | static int |
824 | lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, | 846 | lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
825 | struct lpfc_iocbq *saveq) | 847 | struct lpfc_iocbq *saveq) |
826 | { | 848 | { |
827 | struct lpfc_iocbq * cmdiocbp; | 849 | struct lpfc_iocbq *cmdiocbp; |
828 | int rc = 1; | 850 | int rc = 1; |
829 | unsigned long iflag; | 851 | unsigned long iflag; |
830 | 852 | ||
831 | /* Based on the iotag field, get the cmd IOCB from the txcmplq */ | 853 | /* Based on the iotag field, get the cmd IOCB from the txcmplq */ |
832 | spin_lock_irqsave(phba->host->host_lock, iflag); | 854 | spin_lock_irqsave(&phba->hbalock, iflag); |
833 | cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, saveq); | 855 | cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, saveq); |
856 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
857 | |||
834 | if (cmdiocbp) { | 858 | if (cmdiocbp) { |
835 | if (cmdiocbp->iocb_cmpl) { | 859 | if (cmdiocbp->iocb_cmpl) { |
836 | /* | 860 | /* |
@@ -846,17 +870,8 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, | |||
846 | saveq->iocb.un.ulpWord[4] = | 870 | saveq->iocb.un.ulpWord[4] = |
847 | IOERR_SLI_ABORTED; | 871 | IOERR_SLI_ABORTED; |
848 | } | 872 | } |
849 | spin_unlock_irqrestore(phba->host->host_lock, | ||
850 | iflag); | ||
851 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | ||
852 | spin_lock_irqsave(phba->host->host_lock, iflag); | ||
853 | } | ||
854 | else { | ||
855 | spin_unlock_irqrestore(phba->host->host_lock, | ||
856 | iflag); | ||
857 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | ||
858 | spin_lock_irqsave(phba->host->host_lock, iflag); | ||
859 | } | 873 | } |
874 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | ||
860 | } else | 875 | } else |
861 | lpfc_sli_release_iocbq(phba, cmdiocbp); | 876 | lpfc_sli_release_iocbq(phba, cmdiocbp); |
862 | } else { | 877 | } else { |
@@ -885,12 +900,11 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, | |||
885 | } | 900 | } |
886 | } | 901 | } |
887 | 902 | ||
888 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | ||
889 | return rc; | 903 | return rc; |
890 | } | 904 | } |
891 | 905 | ||
892 | static void lpfc_sli_rsp_pointers_error(struct lpfc_hba * phba, | 906 | static void |
893 | struct lpfc_sli_ring * pring) | 907 | lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) |
894 | { | 908 | { |
895 | struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno]; | 909 | struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno]; |
896 | /* | 910 | /* |
@@ -904,7 +918,7 @@ static void lpfc_sli_rsp_pointers_error(struct lpfc_hba * phba, | |||
904 | le32_to_cpu(pgp->rspPutInx), | 918 | le32_to_cpu(pgp->rspPutInx), |
905 | pring->numRiocb); | 919 | pring->numRiocb); |
906 | 920 | ||
907 | phba->hba_state = LPFC_HBA_ERROR; | 921 | phba->link_state = LPFC_HBA_ERROR; |
908 | 922 | ||
909 | /* | 923 | /* |
910 | * All error attention handlers are posted to | 924 | * All error attention handlers are posted to |
@@ -918,10 +932,10 @@ static void lpfc_sli_rsp_pointers_error(struct lpfc_hba * phba, | |||
918 | return; | 932 | return; |
919 | } | 933 | } |
920 | 934 | ||
921 | void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba) | 935 | void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) |
922 | { | 936 | { |
923 | struct lpfc_sli * psli = &phba->sli; | 937 | struct lpfc_sli *psli = &phba->sli; |
924 | struct lpfc_sli_ring * pring = &psli->ring[LPFC_FCP_RING]; | 938 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_FCP_RING]; |
925 | IOCB_t *irsp = NULL; | 939 | IOCB_t *irsp = NULL; |
926 | IOCB_t *entry = NULL; | 940 | IOCB_t *entry = NULL; |
927 | struct lpfc_iocbq *cmdiocbq = NULL; | 941 | struct lpfc_iocbq *cmdiocbq = NULL; |
@@ -933,6 +947,7 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba) | |||
933 | uint32_t rsp_cmpl = 0; | 947 | uint32_t rsp_cmpl = 0; |
934 | void __iomem *to_slim; | 948 | void __iomem *to_slim; |
935 | uint32_t ha_copy; | 949 | uint32_t ha_copy; |
950 | unsigned long iflags; | ||
936 | 951 | ||
937 | pring->stats.iocb_event++; | 952 | pring->stats.iocb_event++; |
938 | 953 | ||
@@ -960,7 +975,7 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba) | |||
960 | 975 | ||
961 | lpfc_sli_pcimem_bcopy((uint32_t *) entry, | 976 | lpfc_sli_pcimem_bcopy((uint32_t *) entry, |
962 | (uint32_t *) &rspiocbq.iocb, | 977 | (uint32_t *) &rspiocbq.iocb, |
963 | sizeof (IOCB_t)); | 978 | sizeof(IOCB_t)); |
964 | irsp = &rspiocbq.iocb; | 979 | irsp = &rspiocbq.iocb; |
965 | type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK); | 980 | type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK); |
966 | pring->stats.iocb_rsp++; | 981 | pring->stats.iocb_rsp++; |
@@ -998,8 +1013,10 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba) | |||
998 | break; | 1013 | break; |
999 | } | 1014 | } |
1000 | 1015 | ||
1016 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
1001 | cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, | 1017 | cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, |
1002 | &rspiocbq); | 1018 | &rspiocbq); |
1019 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1003 | if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { | 1020 | if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { |
1004 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, | 1021 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, |
1005 | &rspiocbq); | 1022 | &rspiocbq); |
@@ -1045,13 +1062,16 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba) | |||
1045 | ha_copy >>= (LPFC_FCP_RING * 4); | 1062 | ha_copy >>= (LPFC_FCP_RING * 4); |
1046 | 1063 | ||
1047 | if ((rsp_cmpl > 0) && (ha_copy & HA_R0RE_REQ)) { | 1064 | if ((rsp_cmpl > 0) && (ha_copy & HA_R0RE_REQ)) { |
1065 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
1048 | pring->stats.iocb_rsp_full++; | 1066 | pring->stats.iocb_rsp_full++; |
1049 | status = ((CA_R0ATT | CA_R0RE_RSP) << (LPFC_FCP_RING * 4)); | 1067 | status = ((CA_R0ATT | CA_R0RE_RSP) << (LPFC_FCP_RING * 4)); |
1050 | writel(status, phba->CAregaddr); | 1068 | writel(status, phba->CAregaddr); |
1051 | readl(phba->CAregaddr); | 1069 | readl(phba->CAregaddr); |
1070 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1052 | } | 1071 | } |
1053 | if ((ha_copy & HA_R0CE_RSP) && | 1072 | if ((ha_copy & HA_R0CE_RSP) && |
1054 | (pring->flag & LPFC_CALL_RING_AVAILABLE)) { | 1073 | (pring->flag & LPFC_CALL_RING_AVAILABLE)) { |
1074 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
1055 | pring->flag &= ~LPFC_CALL_RING_AVAILABLE; | 1075 | pring->flag &= ~LPFC_CALL_RING_AVAILABLE; |
1056 | pring->stats.iocb_cmd_empty++; | 1076 | pring->stats.iocb_cmd_empty++; |
1057 | 1077 | ||
@@ -1062,6 +1082,7 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba) | |||
1062 | if ((pring->lpfc_sli_cmd_available)) | 1082 | if ((pring->lpfc_sli_cmd_available)) |
1063 | (pring->lpfc_sli_cmd_available) (phba, pring); | 1083 | (pring->lpfc_sli_cmd_available) (phba, pring); |
1064 | 1084 | ||
1085 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1065 | } | 1086 | } |
1066 | 1087 | ||
1067 | return; | 1088 | return; |
@@ -1072,10 +1093,10 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba) | |||
1072 | * to check it explicitly. | 1093 | * to check it explicitly. |
1073 | */ | 1094 | */ |
1074 | static int | 1095 | static int |
1075 | lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, | 1096 | lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, |
1076 | struct lpfc_sli_ring * pring, uint32_t mask) | 1097 | struct lpfc_sli_ring *pring, uint32_t mask) |
1077 | { | 1098 | { |
1078 | struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno]; | 1099 | struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno]; |
1079 | IOCB_t *irsp = NULL; | 1100 | IOCB_t *irsp = NULL; |
1080 | IOCB_t *entry = NULL; | 1101 | IOCB_t *entry = NULL; |
1081 | struct lpfc_iocbq *cmdiocbq = NULL; | 1102 | struct lpfc_iocbq *cmdiocbq = NULL; |
@@ -1086,9 +1107,9 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, | |||
1086 | lpfc_iocb_type type; | 1107 | lpfc_iocb_type type; |
1087 | unsigned long iflag; | 1108 | unsigned long iflag; |
1088 | uint32_t rsp_cmpl = 0; | 1109 | uint32_t rsp_cmpl = 0; |
1089 | void __iomem *to_slim; | 1110 | void __iomem *to_slim; |
1090 | 1111 | ||
1091 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1112 | spin_lock_irqsave(&phba->hbalock, iflag); |
1092 | pring->stats.iocb_event++; | 1113 | pring->stats.iocb_event++; |
1093 | 1114 | ||
1094 | /* | 1115 | /* |
@@ -1099,7 +1120,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, | |||
1099 | portRspPut = le32_to_cpu(pgp->rspPutInx); | 1120 | portRspPut = le32_to_cpu(pgp->rspPutInx); |
1100 | if (unlikely(portRspPut >= portRspMax)) { | 1121 | if (unlikely(portRspPut >= portRspMax)) { |
1101 | lpfc_sli_rsp_pointers_error(phba, pring); | 1122 | lpfc_sli_rsp_pointers_error(phba, pring); |
1102 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1123 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1103 | return 1; | 1124 | return 1; |
1104 | } | 1125 | } |
1105 | 1126 | ||
@@ -1117,7 +1138,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, | |||
1117 | 1138 | ||
1118 | lpfc_sli_pcimem_bcopy((uint32_t *) entry, | 1139 | lpfc_sli_pcimem_bcopy((uint32_t *) entry, |
1119 | (uint32_t *) &rspiocbq.iocb, | 1140 | (uint32_t *) &rspiocbq.iocb, |
1120 | sizeof (IOCB_t)); | 1141 | sizeof(IOCB_t)); |
1121 | INIT_LIST_HEAD(&(rspiocbq.list)); | 1142 | INIT_LIST_HEAD(&(rspiocbq.list)); |
1122 | irsp = &rspiocbq.iocb; | 1143 | irsp = &rspiocbq.iocb; |
1123 | 1144 | ||
@@ -1161,19 +1182,19 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, | |||
1161 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, | 1182 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, |
1162 | &rspiocbq); | 1183 | &rspiocbq); |
1163 | } else { | 1184 | } else { |
1164 | spin_unlock_irqrestore( | 1185 | spin_unlock_irqrestore(&phba->hbalock, |
1165 | phba->host->host_lock, iflag); | 1186 | iflag); |
1166 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, | 1187 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, |
1167 | &rspiocbq); | 1188 | &rspiocbq); |
1168 | spin_lock_irqsave(phba->host->host_lock, | 1189 | spin_lock_irqsave(&phba->hbalock, |
1169 | iflag); | 1190 | iflag); |
1170 | } | 1191 | } |
1171 | } | 1192 | } |
1172 | break; | 1193 | break; |
1173 | case LPFC_UNSOL_IOCB: | 1194 | case LPFC_UNSOL_IOCB: |
1174 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1195 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1175 | lpfc_sli_process_unsol_iocb(phba, pring, &rspiocbq); | 1196 | lpfc_sli_process_unsol_iocb(phba, pring, &rspiocbq); |
1176 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1197 | spin_lock_irqsave(&phba->hbalock, iflag); |
1177 | break; | 1198 | break; |
1178 | default: | 1199 | default: |
1179 | if (irsp->ulpCommand == CMD_ADAPTER_MSG) { | 1200 | if (irsp->ulpCommand == CMD_ADAPTER_MSG) { |
@@ -1228,31 +1249,31 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, | |||
1228 | 1249 | ||
1229 | } | 1250 | } |
1230 | 1251 | ||
1231 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1252 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1232 | return rc; | 1253 | return rc; |
1233 | } | 1254 | } |
1234 | 1255 | ||
1235 | 1256 | ||
1236 | int | 1257 | int |
1237 | lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | 1258 | lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, |
1238 | struct lpfc_sli_ring * pring, uint32_t mask) | 1259 | struct lpfc_sli_ring *pring, uint32_t mask) |
1239 | { | 1260 | { |
1261 | struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno]; | ||
1240 | IOCB_t *entry; | 1262 | IOCB_t *entry; |
1241 | IOCB_t *irsp = NULL; | 1263 | IOCB_t *irsp = NULL; |
1242 | struct lpfc_iocbq *rspiocbp = NULL; | 1264 | struct lpfc_iocbq *rspiocbp = NULL; |
1243 | struct lpfc_iocbq *next_iocb; | 1265 | struct lpfc_iocbq *next_iocb; |
1244 | struct lpfc_iocbq *cmdiocbp; | 1266 | struct lpfc_iocbq *cmdiocbp; |
1245 | struct lpfc_iocbq *saveq; | 1267 | struct lpfc_iocbq *saveq; |
1246 | struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno]; | ||
1247 | uint8_t iocb_cmd_type; | 1268 | uint8_t iocb_cmd_type; |
1248 | lpfc_iocb_type type; | 1269 | lpfc_iocb_type type; |
1249 | uint32_t status, free_saveq; | 1270 | uint32_t status, free_saveq; |
1250 | uint32_t portRspPut, portRspMax; | 1271 | uint32_t portRspPut, portRspMax; |
1251 | int rc = 1; | 1272 | int rc = 1; |
1252 | unsigned long iflag; | 1273 | unsigned long iflag; |
1253 | void __iomem *to_slim; | 1274 | void __iomem *to_slim; |
1254 | 1275 | ||
1255 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1276 | spin_lock_irqsave(&phba->hbalock, iflag); |
1256 | pring->stats.iocb_event++; | 1277 | pring->stats.iocb_event++; |
1257 | 1278 | ||
1258 | /* | 1279 | /* |
@@ -1274,8 +1295,8 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | |||
1274 | phba->brd_no, | 1295 | phba->brd_no, |
1275 | pring->ringno, portRspPut, portRspMax); | 1296 | pring->ringno, portRspPut, portRspMax); |
1276 | 1297 | ||
1277 | phba->hba_state = LPFC_HBA_ERROR; | 1298 | phba->link_state = LPFC_HBA_ERROR; |
1278 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1299 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1279 | 1300 | ||
1280 | phba->work_hs = HS_FFER3; | 1301 | phba->work_hs = HS_FFER3; |
1281 | lpfc_handle_eratt(phba); | 1302 | lpfc_handle_eratt(phba); |
@@ -1299,14 +1320,14 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | |||
1299 | * received. | 1320 | * received. |
1300 | */ | 1321 | */ |
1301 | entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx); | 1322 | entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx); |
1302 | rspiocbp = lpfc_sli_get_iocbq(phba); | 1323 | rspiocbp = __lpfc_sli_get_iocbq(phba); |
1303 | if (rspiocbp == NULL) { | 1324 | if (rspiocbp == NULL) { |
1304 | printk(KERN_ERR "%s: out of buffers! Failing " | 1325 | printk(KERN_ERR "%s: out of buffers! Failing " |
1305 | "completion.\n", __FUNCTION__); | 1326 | "completion.\n", __FUNCTION__); |
1306 | break; | 1327 | break; |
1307 | } | 1328 | } |
1308 | 1329 | ||
1309 | lpfc_sli_pcimem_bcopy(entry, &rspiocbp->iocb, sizeof (IOCB_t)); | 1330 | lpfc_sli_pcimem_bcopy(entry, &rspiocbp->iocb, sizeof(IOCB_t)); |
1310 | irsp = &rspiocbp->iocb; | 1331 | irsp = &rspiocbp->iocb; |
1311 | 1332 | ||
1312 | if (++pring->rspidx >= portRspMax) | 1333 | if (++pring->rspidx >= portRspMax) |
@@ -1366,17 +1387,17 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | |||
1366 | iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK; | 1387 | iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK; |
1367 | type = lpfc_sli_iocb_cmd_type(iocb_cmd_type); | 1388 | type = lpfc_sli_iocb_cmd_type(iocb_cmd_type); |
1368 | if (type == LPFC_SOL_IOCB) { | 1389 | if (type == LPFC_SOL_IOCB) { |
1369 | spin_unlock_irqrestore(phba->host->host_lock, | 1390 | spin_unlock_irqrestore(&phba->hbalock, |
1370 | iflag); | 1391 | iflag); |
1371 | rc = lpfc_sli_process_sol_iocb(phba, pring, | 1392 | rc = lpfc_sli_process_sol_iocb(phba, pring, |
1372 | saveq); | 1393 | saveq); |
1373 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1394 | spin_lock_irqsave(&phba->hbalock, iflag); |
1374 | } else if (type == LPFC_UNSOL_IOCB) { | 1395 | } else if (type == LPFC_UNSOL_IOCB) { |
1375 | spin_unlock_irqrestore(phba->host->host_lock, | 1396 | spin_unlock_irqrestore(&phba->hbalock, |
1376 | iflag); | 1397 | iflag); |
1377 | rc = lpfc_sli_process_unsol_iocb(phba, pring, | 1398 | rc = lpfc_sli_process_unsol_iocb(phba, pring, |
1378 | saveq); | 1399 | saveq); |
1379 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1400 | spin_lock_irqsave(&phba->hbalock, iflag); |
1380 | } else if (type == LPFC_ABORT_IOCB) { | 1401 | } else if (type == LPFC_ABORT_IOCB) { |
1381 | if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) && | 1402 | if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) && |
1382 | ((cmdiocbp = | 1403 | ((cmdiocbp = |
@@ -1386,15 +1407,15 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | |||
1386 | routine */ | 1407 | routine */ |
1387 | if (cmdiocbp->iocb_cmpl) { | 1408 | if (cmdiocbp->iocb_cmpl) { |
1388 | spin_unlock_irqrestore( | 1409 | spin_unlock_irqrestore( |
1389 | phba->host->host_lock, | 1410 | &phba->hbalock, |
1390 | iflag); | 1411 | iflag); |
1391 | (cmdiocbp->iocb_cmpl) (phba, | 1412 | (cmdiocbp->iocb_cmpl) (phba, |
1392 | cmdiocbp, saveq); | 1413 | cmdiocbp, saveq); |
1393 | spin_lock_irqsave( | 1414 | spin_lock_irqsave( |
1394 | phba->host->host_lock, | 1415 | &phba->hbalock, |
1395 | iflag); | 1416 | iflag); |
1396 | } else | 1417 | } else |
1397 | lpfc_sli_release_iocbq(phba, | 1418 | __lpfc_sli_release_iocbq(phba, |
1398 | cmdiocbp); | 1419 | cmdiocbp); |
1399 | } | 1420 | } |
1400 | } else if (type == LPFC_UNKNOWN_IOCB) { | 1421 | } else if (type == LPFC_UNKNOWN_IOCB) { |
@@ -1425,17 +1446,13 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | |||
1425 | } | 1446 | } |
1426 | 1447 | ||
1427 | if (free_saveq) { | 1448 | if (free_saveq) { |
1428 | if (!list_empty(&saveq->list)) { | 1449 | list_for_each_entry_safe(rspiocbp, next_iocb, |
1429 | list_for_each_entry_safe(rspiocbp, | 1450 | &saveq->list, list) { |
1430 | next_iocb, | 1451 | list_del(&rspiocbp->list); |
1431 | &saveq->list, | 1452 | __lpfc_sli_release_iocbq(phba, |
1432 | list) { | 1453 | rspiocbp); |
1433 | list_del(&rspiocbp->list); | ||
1434 | lpfc_sli_release_iocbq(phba, | ||
1435 | rspiocbp); | ||
1436 | } | ||
1437 | } | 1454 | } |
1438 | lpfc_sli_release_iocbq(phba, saveq); | 1455 | __lpfc_sli_release_iocbq(phba, saveq); |
1439 | } | 1456 | } |
1440 | } | 1457 | } |
1441 | 1458 | ||
@@ -1470,24 +1487,21 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, | |||
1470 | 1487 | ||
1471 | } | 1488 | } |
1472 | 1489 | ||
1473 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1490 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1474 | return rc; | 1491 | return rc; |
1475 | } | 1492 | } |
1476 | 1493 | ||
1477 | int | 1494 | void |
1478 | lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | 1495 | lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) |
1479 | { | 1496 | { |
1480 | LIST_HEAD(completions); | 1497 | LIST_HEAD(completions); |
1481 | struct lpfc_iocbq *iocb, *next_iocb; | 1498 | struct lpfc_iocbq *iocb, *next_iocb; |
1482 | IOCB_t *cmd = NULL; | 1499 | IOCB_t *cmd = NULL; |
1483 | int errcnt; | ||
1484 | |||
1485 | errcnt = 0; | ||
1486 | 1500 | ||
1487 | /* Error everything on txq and txcmplq | 1501 | /* Error everything on txq and txcmplq |
1488 | * First do the txq. | 1502 | * First do the txq. |
1489 | */ | 1503 | */ |
1490 | spin_lock_irq(phba->host->host_lock); | 1504 | spin_lock_irq(&phba->hbalock); |
1491 | list_splice_init(&pring->txq, &completions); | 1505 | list_splice_init(&pring->txq, &completions); |
1492 | pring->txq_cnt = 0; | 1506 | pring->txq_cnt = 0; |
1493 | 1507 | ||
@@ -1495,26 +1509,25 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
1495 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) | 1509 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) |
1496 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); | 1510 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
1497 | 1511 | ||
1498 | spin_unlock_irq(phba->host->host_lock); | 1512 | spin_unlock_irq(&phba->hbalock); |
1499 | 1513 | ||
1500 | while (!list_empty(&completions)) { | 1514 | while (!list_empty(&completions)) { |
1501 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | 1515 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); |
1502 | cmd = &iocb->iocb; | 1516 | cmd = &iocb->iocb; |
1503 | list_del(&iocb->list); | 1517 | list_del(&iocb->list); |
1504 | 1518 | ||
1505 | if (iocb->iocb_cmpl) { | 1519 | if (!iocb->iocb_cmpl) |
1520 | lpfc_sli_release_iocbq(phba, iocb); | ||
1521 | else { | ||
1506 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 1522 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
1507 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | 1523 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
1508 | (iocb->iocb_cmpl) (phba, iocb, iocb); | 1524 | (iocb->iocb_cmpl) (phba, iocb, iocb); |
1509 | } else | 1525 | } |
1510 | lpfc_sli_release_iocbq(phba, iocb); | ||
1511 | } | 1526 | } |
1512 | |||
1513 | return errcnt; | ||
1514 | } | 1527 | } |
1515 | 1528 | ||
1516 | int | 1529 | int |
1517 | lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask) | 1530 | lpfc_sli_brdready(struct lpfc_hba *phba, uint32_t mask) |
1518 | { | 1531 | { |
1519 | uint32_t status; | 1532 | uint32_t status; |
1520 | int i = 0; | 1533 | int i = 0; |
@@ -1541,7 +1554,8 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask) | |||
1541 | msleep(2500); | 1554 | msleep(2500); |
1542 | 1555 | ||
1543 | if (i == 15) { | 1556 | if (i == 15) { |
1544 | phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */ | 1557 | /* Do post */ |
1558 | phba->pport->port_state = LPFC_STATE_UNKNOWN; | ||
1545 | lpfc_sli_brdrestart(phba); | 1559 | lpfc_sli_brdrestart(phba); |
1546 | } | 1560 | } |
1547 | /* Read the HBA Host Status Register */ | 1561 | /* Read the HBA Host Status Register */ |
@@ -1550,7 +1564,7 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask) | |||
1550 | 1564 | ||
1551 | /* Check to see if any errors occurred during init */ | 1565 | /* Check to see if any errors occurred during init */ |
1552 | if ((status & HS_FFERM) || (i >= 20)) { | 1566 | if ((status & HS_FFERM) || (i >= 20)) { |
1553 | phba->hba_state = LPFC_HBA_ERROR; | 1567 | phba->link_state = LPFC_HBA_ERROR; |
1554 | retval = 1; | 1568 | retval = 1; |
1555 | } | 1569 | } |
1556 | 1570 | ||
@@ -1559,7 +1573,7 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask) | |||
1559 | 1573 | ||
1560 | #define BARRIER_TEST_PATTERN (0xdeadbeef) | 1574 | #define BARRIER_TEST_PATTERN (0xdeadbeef) |
1561 | 1575 | ||
1562 | void lpfc_reset_barrier(struct lpfc_hba * phba) | 1576 | void lpfc_reset_barrier(struct lpfc_hba *phba) |
1563 | { | 1577 | { |
1564 | uint32_t __iomem *resp_buf; | 1578 | uint32_t __iomem *resp_buf; |
1565 | uint32_t __iomem *mbox_buf; | 1579 | uint32_t __iomem *mbox_buf; |
@@ -1584,12 +1598,12 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) | |||
1584 | hc_copy = readl(phba->HCregaddr); | 1598 | hc_copy = readl(phba->HCregaddr); |
1585 | writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr); | 1599 | writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr); |
1586 | readl(phba->HCregaddr); /* flush */ | 1600 | readl(phba->HCregaddr); /* flush */ |
1587 | phba->fc_flag |= FC_IGNORE_ERATT; | 1601 | phba->link_flag |= LS_IGNORE_ERATT; |
1588 | 1602 | ||
1589 | if (readl(phba->HAregaddr) & HA_ERATT) { | 1603 | if (readl(phba->HAregaddr) & HA_ERATT) { |
1590 | /* Clear Chip error bit */ | 1604 | /* Clear Chip error bit */ |
1591 | writel(HA_ERATT, phba->HAregaddr); | 1605 | writel(HA_ERATT, phba->HAregaddr); |
1592 | phba->stopped = 1; | 1606 | phba->pport->stopped = 1; |
1593 | } | 1607 | } |
1594 | 1608 | ||
1595 | mbox = 0; | 1609 | mbox = 0; |
@@ -1606,7 +1620,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) | |||
1606 | 1620 | ||
1607 | if (readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN)) { | 1621 | if (readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN)) { |
1608 | if (phba->sli.sli_flag & LPFC_SLI2_ACTIVE || | 1622 | if (phba->sli.sli_flag & LPFC_SLI2_ACTIVE || |
1609 | phba->stopped) | 1623 | phba->pport->stopped) |
1610 | goto restore_hc; | 1624 | goto restore_hc; |
1611 | else | 1625 | else |
1612 | goto clear_errat; | 1626 | goto clear_errat; |
@@ -1623,17 +1637,17 @@ clear_errat: | |||
1623 | 1637 | ||
1624 | if (readl(phba->HAregaddr) & HA_ERATT) { | 1638 | if (readl(phba->HAregaddr) & HA_ERATT) { |
1625 | writel(HA_ERATT, phba->HAregaddr); | 1639 | writel(HA_ERATT, phba->HAregaddr); |
1626 | phba->stopped = 1; | 1640 | phba->pport->stopped = 1; |
1627 | } | 1641 | } |
1628 | 1642 | ||
1629 | restore_hc: | 1643 | restore_hc: |
1630 | phba->fc_flag &= ~FC_IGNORE_ERATT; | 1644 | phba->link_flag &= ~LS_IGNORE_ERATT; |
1631 | writel(hc_copy, phba->HCregaddr); | 1645 | writel(hc_copy, phba->HCregaddr); |
1632 | readl(phba->HCregaddr); /* flush */ | 1646 | readl(phba->HCregaddr); /* flush */ |
1633 | } | 1647 | } |
1634 | 1648 | ||
1635 | int | 1649 | int |
1636 | lpfc_sli_brdkill(struct lpfc_hba * phba) | 1650 | lpfc_sli_brdkill(struct lpfc_hba *phba) |
1637 | { | 1651 | { |
1638 | struct lpfc_sli *psli; | 1652 | struct lpfc_sli *psli; |
1639 | LPFC_MBOXQ_t *pmb; | 1653 | LPFC_MBOXQ_t *pmb; |
@@ -1650,7 +1664,7 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) | |||
1650 | LOG_SLI, | 1664 | LOG_SLI, |
1651 | "%d:0329 Kill HBA Data: x%x x%x\n", | 1665 | "%d:0329 Kill HBA Data: x%x x%x\n", |
1652 | phba->brd_no, | 1666 | phba->brd_no, |
1653 | phba->hba_state, | 1667 | phba->pport->port_state, |
1654 | psli->sli_flag); | 1668 | psli->sli_flag); |
1655 | 1669 | ||
1656 | if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, | 1670 | if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, |
@@ -1658,13 +1672,13 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) | |||
1658 | return 1; | 1672 | return 1; |
1659 | 1673 | ||
1660 | /* Disable the error attention */ | 1674 | /* Disable the error attention */ |
1661 | spin_lock_irq(phba->host->host_lock); | 1675 | spin_lock_irq(&phba->hbalock); |
1662 | status = readl(phba->HCregaddr); | 1676 | status = readl(phba->HCregaddr); |
1663 | status &= ~HC_ERINT_ENA; | 1677 | status &= ~HC_ERINT_ENA; |
1664 | writel(status, phba->HCregaddr); | 1678 | writel(status, phba->HCregaddr); |
1665 | readl(phba->HCregaddr); /* flush */ | 1679 | readl(phba->HCregaddr); /* flush */ |
1666 | phba->fc_flag |= FC_IGNORE_ERATT; | 1680 | phba->link_flag |= LS_IGNORE_ERATT; |
1667 | spin_unlock_irq(phba->host->host_lock); | 1681 | spin_unlock_irq(&phba->hbalock); |
1668 | 1682 | ||
1669 | lpfc_kill_board(phba, pmb); | 1683 | lpfc_kill_board(phba, pmb); |
1670 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1684 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
@@ -1673,9 +1687,9 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) | |||
1673 | if (retval != MBX_SUCCESS) { | 1687 | if (retval != MBX_SUCCESS) { |
1674 | if (retval != MBX_BUSY) | 1688 | if (retval != MBX_BUSY) |
1675 | mempool_free(pmb, phba->mbox_mem_pool); | 1689 | mempool_free(pmb, phba->mbox_mem_pool); |
1676 | spin_lock_irq(phba->host->host_lock); | 1690 | spin_lock_irq(&phba->hbalock); |
1677 | phba->fc_flag &= ~FC_IGNORE_ERATT; | 1691 | phba->link_flag &= ~LS_IGNORE_ERATT; |
1678 | spin_unlock_irq(phba->host->host_lock); | 1692 | spin_unlock_irq(&phba->hbalock); |
1679 | return 1; | 1693 | return 1; |
1680 | } | 1694 | } |
1681 | 1695 | ||
@@ -1698,22 +1712,22 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) | |||
1698 | del_timer_sync(&psli->mbox_tmo); | 1712 | del_timer_sync(&psli->mbox_tmo); |
1699 | if (ha_copy & HA_ERATT) { | 1713 | if (ha_copy & HA_ERATT) { |
1700 | writel(HA_ERATT, phba->HAregaddr); | 1714 | writel(HA_ERATT, phba->HAregaddr); |
1701 | phba->stopped = 1; | 1715 | phba->pport->stopped = 1; |
1702 | } | 1716 | } |
1703 | spin_lock_irq(phba->host->host_lock); | 1717 | spin_lock_irq(&phba->hbalock); |
1704 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 1718 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
1705 | phba->fc_flag &= ~FC_IGNORE_ERATT; | 1719 | phba->link_flag &= ~LS_IGNORE_ERATT; |
1706 | spin_unlock_irq(phba->host->host_lock); | 1720 | spin_unlock_irq(&phba->hbalock); |
1707 | 1721 | ||
1708 | psli->mbox_active = NULL; | 1722 | psli->mbox_active = NULL; |
1709 | lpfc_hba_down_post(phba); | 1723 | lpfc_hba_down_post(phba); |
1710 | phba->hba_state = LPFC_HBA_ERROR; | 1724 | phba->link_state = LPFC_HBA_ERROR; |
1711 | 1725 | ||
1712 | return (ha_copy & HA_ERATT ? 0 : 1); | 1726 | return ha_copy & HA_ERATT ? 0 : 1; |
1713 | } | 1727 | } |
1714 | 1728 | ||
1715 | int | 1729 | int |
1716 | lpfc_sli_brdreset(struct lpfc_hba * phba) | 1730 | lpfc_sli_brdreset(struct lpfc_hba *phba) |
1717 | { | 1731 | { |
1718 | struct lpfc_sli *psli; | 1732 | struct lpfc_sli *psli; |
1719 | struct lpfc_sli_ring *pring; | 1733 | struct lpfc_sli_ring *pring; |
@@ -1725,12 +1739,12 @@ lpfc_sli_brdreset(struct lpfc_hba * phba) | |||
1725 | /* Reset HBA */ | 1739 | /* Reset HBA */ |
1726 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 1740 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
1727 | "%d:0325 Reset HBA Data: x%x x%x\n", phba->brd_no, | 1741 | "%d:0325 Reset HBA Data: x%x x%x\n", phba->brd_no, |
1728 | phba->hba_state, psli->sli_flag); | 1742 | phba->pport->port_state, psli->sli_flag); |
1729 | 1743 | ||
1730 | /* perform board reset */ | 1744 | /* perform board reset */ |
1731 | phba->fc_eventTag = 0; | 1745 | phba->fc_eventTag = 0; |
1732 | phba->fc_myDID = 0; | 1746 | phba->pport->fc_myDID = 0; |
1733 | phba->fc_prevDID = 0; | 1747 | phba->pport->fc_prevDID = 0; |
1734 | 1748 | ||
1735 | /* Turn off parity checking and serr during the physical reset */ | 1749 | /* Turn off parity checking and serr during the physical reset */ |
1736 | pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value); | 1750 | pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value); |
@@ -1760,12 +1774,12 @@ lpfc_sli_brdreset(struct lpfc_hba * phba) | |||
1760 | pring->missbufcnt = 0; | 1774 | pring->missbufcnt = 0; |
1761 | } | 1775 | } |
1762 | 1776 | ||
1763 | phba->hba_state = LPFC_WARM_START; | 1777 | phba->link_state = LPFC_WARM_START; |
1764 | return 0; | 1778 | return 0; |
1765 | } | 1779 | } |
1766 | 1780 | ||
1767 | int | 1781 | int |
1768 | lpfc_sli_brdrestart(struct lpfc_hba * phba) | 1782 | lpfc_sli_brdrestart(struct lpfc_hba *phba) |
1769 | { | 1783 | { |
1770 | MAILBOX_t *mb; | 1784 | MAILBOX_t *mb; |
1771 | struct lpfc_sli *psli; | 1785 | struct lpfc_sli *psli; |
@@ -1773,14 +1787,14 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba) | |||
1773 | volatile uint32_t word0; | 1787 | volatile uint32_t word0; |
1774 | void __iomem *to_slim; | 1788 | void __iomem *to_slim; |
1775 | 1789 | ||
1776 | spin_lock_irq(phba->host->host_lock); | 1790 | spin_lock_irq(&phba->hbalock); |
1777 | 1791 | ||
1778 | psli = &phba->sli; | 1792 | psli = &phba->sli; |
1779 | 1793 | ||
1780 | /* Restart HBA */ | 1794 | /* Restart HBA */ |
1781 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 1795 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
1782 | "%d:0337 Restart HBA Data: x%x x%x\n", phba->brd_no, | 1796 | "%d:0337 Restart HBA Data: x%x x%x\n", phba->brd_no, |
1783 | phba->hba_state, psli->sli_flag); | 1797 | phba->pport->port_state, psli->sli_flag); |
1784 | 1798 | ||
1785 | word0 = 0; | 1799 | word0 = 0; |
1786 | mb = (MAILBOX_t *) &word0; | 1800 | mb = (MAILBOX_t *) &word0; |
@@ -1794,7 +1808,7 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba) | |||
1794 | readl(to_slim); /* flush */ | 1808 | readl(to_slim); /* flush */ |
1795 | 1809 | ||
1796 | /* Only skip post after fc_ffinit is completed */ | 1810 | /* Only skip post after fc_ffinit is completed */ |
1797 | if (phba->hba_state) { | 1811 | if (phba->pport->port_state) { |
1798 | skip_post = 1; | 1812 | skip_post = 1; |
1799 | word0 = 1; /* This is really setting up word1 */ | 1813 | word0 = 1; /* This is really setting up word1 */ |
1800 | } else { | 1814 | } else { |
@@ -1806,10 +1820,10 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba) | |||
1806 | readl(to_slim); /* flush */ | 1820 | readl(to_slim); /* flush */ |
1807 | 1821 | ||
1808 | lpfc_sli_brdreset(phba); | 1822 | lpfc_sli_brdreset(phba); |
1809 | phba->stopped = 0; | 1823 | phba->pport->stopped = 0; |
1810 | phba->hba_state = LPFC_INIT_START; | 1824 | phba->link_state = LPFC_INIT_START; |
1811 | 1825 | ||
1812 | spin_unlock_irq(phba->host->host_lock); | 1826 | spin_unlock_irq(&phba->hbalock); |
1813 | 1827 | ||
1814 | memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets)); | 1828 | memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets)); |
1815 | psli->stats_start = get_seconds(); | 1829 | psli->stats_start = get_seconds(); |
@@ -1850,7 +1864,7 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
1850 | "timeout, status reg x%x\n", | 1864 | "timeout, status reg x%x\n", |
1851 | phba->brd_no, | 1865 | phba->brd_no, |
1852 | status); | 1866 | status); |
1853 | phba->hba_state = LPFC_HBA_ERROR; | 1867 | phba->link_state = LPFC_HBA_ERROR; |
1854 | return -ETIMEDOUT; | 1868 | return -ETIMEDOUT; |
1855 | } | 1869 | } |
1856 | 1870 | ||
@@ -1866,7 +1880,7 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
1866 | "chipset, status reg x%x\n", | 1880 | "chipset, status reg x%x\n", |
1867 | phba->brd_no, | 1881 | phba->brd_no, |
1868 | status); | 1882 | status); |
1869 | phba->hba_state = LPFC_HBA_ERROR; | 1883 | phba->link_state = LPFC_HBA_ERROR; |
1870 | return -EIO; | 1884 | return -EIO; |
1871 | } | 1885 | } |
1872 | 1886 | ||
@@ -1879,7 +1893,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
1879 | } | 1893 | } |
1880 | 1894 | ||
1881 | if (i == 15) { | 1895 | if (i == 15) { |
1882 | phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */ | 1896 | /* Do post */ |
1897 | phba->pport->port_state = LPFC_STATE_UNKNOWN; | ||
1883 | lpfc_sli_brdrestart(phba); | 1898 | lpfc_sli_brdrestart(phba); |
1884 | } | 1899 | } |
1885 | /* Read the HBA Host Status Register */ | 1900 | /* Read the HBA Host Status Register */ |
@@ -1897,7 +1912,7 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
1897 | "status reg x%x\n", | 1912 | "status reg x%x\n", |
1898 | phba->brd_no, | 1913 | phba->brd_no, |
1899 | status); | 1914 | status); |
1900 | phba->hba_state = LPFC_HBA_ERROR; | 1915 | phba->link_state = LPFC_HBA_ERROR; |
1901 | return -EIO; | 1916 | return -EIO; |
1902 | } | 1917 | } |
1903 | 1918 | ||
@@ -1912,31 +1927,31 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
1912 | } | 1927 | } |
1913 | 1928 | ||
1914 | int | 1929 | int |
1915 | lpfc_sli_hba_setup(struct lpfc_hba * phba) | 1930 | lpfc_sli_hba_setup(struct lpfc_hba *phba) |
1916 | { | 1931 | { |
1917 | LPFC_MBOXQ_t *pmb; | 1932 | LPFC_MBOXQ_t *pmb; |
1918 | uint32_t resetcount = 0, rc = 0, done = 0; | 1933 | uint32_t resetcount = 0, rc = 0, done = 0; |
1919 | 1934 | ||
1920 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1935 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
1921 | if (!pmb) { | 1936 | if (!pmb) { |
1922 | phba->hba_state = LPFC_HBA_ERROR; | 1937 | phba->link_state = LPFC_HBA_ERROR; |
1923 | return -ENOMEM; | 1938 | return -ENOMEM; |
1924 | } | 1939 | } |
1925 | 1940 | ||
1926 | while (resetcount < 2 && !done) { | 1941 | while (resetcount < 2 && !done) { |
1927 | spin_lock_irq(phba->host->host_lock); | 1942 | spin_lock_irq(&phba->hbalock); |
1928 | phba->sli.sli_flag |= LPFC_SLI_MBOX_ACTIVE; | 1943 | phba->sli.sli_flag |= LPFC_SLI_MBOX_ACTIVE; |
1929 | spin_unlock_irq(phba->host->host_lock); | 1944 | spin_unlock_irq(&phba->hbalock); |
1930 | phba->hba_state = LPFC_STATE_UNKNOWN; | 1945 | phba->pport->port_state = LPFC_STATE_UNKNOWN; |
1931 | lpfc_sli_brdrestart(phba); | 1946 | lpfc_sli_brdrestart(phba); |
1932 | msleep(2500); | 1947 | msleep(2500); |
1933 | rc = lpfc_sli_chipset_init(phba); | 1948 | rc = lpfc_sli_chipset_init(phba); |
1934 | if (rc) | 1949 | if (rc) |
1935 | break; | 1950 | break; |
1936 | 1951 | ||
1937 | spin_lock_irq(phba->host->host_lock); | 1952 | spin_lock_irq(&phba->hbalock); |
1938 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 1953 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
1939 | spin_unlock_irq(phba->host->host_lock); | 1954 | spin_unlock_irq(&phba->hbalock); |
1940 | resetcount++; | 1955 | resetcount++; |
1941 | 1956 | ||
1942 | /* Call pre CONFIG_PORT mailbox command initialization. A value of 0 | 1957 | /* Call pre CONFIG_PORT mailbox command initialization. A value of 0 |
@@ -1946,13 +1961,13 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba) | |||
1946 | */ | 1961 | */ |
1947 | rc = lpfc_config_port_prep(phba); | 1962 | rc = lpfc_config_port_prep(phba); |
1948 | if (rc == -ERESTART) { | 1963 | if (rc == -ERESTART) { |
1949 | phba->hba_state = 0; | 1964 | phba->pport->port_state = 0; |
1950 | continue; | 1965 | continue; |
1951 | } else if (rc) { | 1966 | } else if (rc) { |
1952 | break; | 1967 | break; |
1953 | } | 1968 | } |
1954 | 1969 | ||
1955 | phba->hba_state = LPFC_INIT_MBX_CMDS; | 1970 | phba->link_state = LPFC_INIT_MBX_CMDS; |
1956 | lpfc_config_port(phba, pmb); | 1971 | lpfc_config_port(phba, pmb); |
1957 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | 1972 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); |
1958 | if (rc == MBX_SUCCESS) | 1973 | if (rc == MBX_SUCCESS) |
@@ -1963,7 +1978,10 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba) | |||
1963 | "CONFIG_PORT, mbxStatus x%x Data: x%x\n", | 1978 | "CONFIG_PORT, mbxStatus x%x Data: x%x\n", |
1964 | phba->brd_no, pmb->mb.mbxCommand, | 1979 | phba->brd_no, pmb->mb.mbxCommand, |
1965 | pmb->mb.mbxStatus, 0); | 1980 | pmb->mb.mbxStatus, 0); |
1981 | spin_lock_irq(&phba->hbalock); | ||
1966 | phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE; | 1982 | phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE; |
1983 | spin_unlock_irq(&phba->hbalock); | ||
1984 | rc = -ENXIO; | ||
1967 | } | 1985 | } |
1968 | } | 1986 | } |
1969 | if (!done) | 1987 | if (!done) |
@@ -1982,7 +2000,7 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba) | |||
1982 | 2000 | ||
1983 | goto lpfc_sli_hba_setup_exit; | 2001 | goto lpfc_sli_hba_setup_exit; |
1984 | lpfc_sli_hba_setup_error: | 2002 | lpfc_sli_hba_setup_error: |
1985 | phba->hba_state = LPFC_HBA_ERROR; | 2003 | phba->link_state = LPFC_HBA_ERROR; |
1986 | lpfc_sli_hba_setup_exit: | 2004 | lpfc_sli_hba_setup_exit: |
1987 | mempool_free(pmb, phba->mbox_mem_pool); | 2005 | mempool_free(pmb, phba->mbox_mem_pool); |
1988 | return rc; | 2006 | return rc; |
@@ -2004,36 +2022,34 @@ lpfc_sli_hba_setup_exit: | |||
2004 | void | 2022 | void |
2005 | lpfc_mbox_timeout(unsigned long ptr) | 2023 | lpfc_mbox_timeout(unsigned long ptr) |
2006 | { | 2024 | { |
2007 | struct lpfc_hba *phba; | 2025 | struct lpfc_hba *phba = (struct lpfc_hba *) phba; |
2008 | unsigned long iflag; | 2026 | unsigned long iflag; |
2027 | uint32_t tmo_posted; | ||
2009 | 2028 | ||
2010 | phba = (struct lpfc_hba *)ptr; | 2029 | spin_lock_irqsave(&phba->pport->work_port_lock, iflag); |
2011 | spin_lock_irqsave(phba->host->host_lock, iflag); | 2030 | tmo_posted = (phba->pport->work_port_events & WORKER_MBOX_TMO) == 0; |
2012 | if (!(phba->work_hba_events & WORKER_MBOX_TMO)) { | 2031 | if (!tmo_posted) |
2013 | phba->work_hba_events |= WORKER_MBOX_TMO; | 2032 | phba->pport->work_port_events |= WORKER_MBOX_TMO; |
2033 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); | ||
2034 | |||
2035 | if (!tmo_posted) { | ||
2014 | if (phba->work_wait) | 2036 | if (phba->work_wait) |
2015 | wake_up(phba->work_wait); | 2037 | wake_up(phba->work_wait); |
2016 | } | 2038 | } |
2017 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | ||
2018 | } | 2039 | } |
2019 | 2040 | ||
2020 | void | 2041 | void |
2021 | lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | 2042 | lpfc_mbox_timeout_handler(struct lpfc_hba *phba) |
2022 | { | 2043 | { |
2023 | LPFC_MBOXQ_t *pmbox; | 2044 | LPFC_MBOXQ_t *pmbox = phba->sli.mbox_active; |
2024 | MAILBOX_t *mb; | 2045 | MAILBOX_t *mb = &pmbox->mb; |
2025 | struct lpfc_sli *psli = &phba->sli; | 2046 | struct lpfc_sli *psli = &phba->sli; |
2026 | struct lpfc_sli_ring *pring; | 2047 | struct lpfc_sli_ring *pring; |
2027 | 2048 | ||
2028 | spin_lock_irq(phba->host->host_lock); | 2049 | if (!(phba->pport->work_port_events & WORKER_MBOX_TMO)) { |
2029 | if (!(phba->work_hba_events & WORKER_MBOX_TMO)) { | ||
2030 | spin_unlock_irq(phba->host->host_lock); | ||
2031 | return; | 2050 | return; |
2032 | } | 2051 | } |
2033 | 2052 | ||
2034 | pmbox = phba->sli.mbox_active; | ||
2035 | mb = &pmbox->mb; | ||
2036 | |||
2037 | /* Mbox cmd <mbxCommand> timeout */ | 2053 | /* Mbox cmd <mbxCommand> timeout */ |
2038 | lpfc_printf_log(phba, | 2054 | lpfc_printf_log(phba, |
2039 | KERN_ERR, | 2055 | KERN_ERR, |
@@ -2041,7 +2057,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2041 | "%d:0310 Mailbox command x%x timeout Data: x%x x%x x%p\n", | 2057 | "%d:0310 Mailbox command x%x timeout Data: x%x x%x x%p\n", |
2042 | phba->brd_no, | 2058 | phba->brd_no, |
2043 | mb->mbxCommand, | 2059 | mb->mbxCommand, |
2044 | phba->hba_state, | 2060 | phba->pport->port_state, |
2045 | phba->sli.sli_flag, | 2061 | phba->sli.sli_flag, |
2046 | phba->sli.mbox_active); | 2062 | phba->sli.mbox_active); |
2047 | 2063 | ||
@@ -2049,11 +2065,14 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2049 | * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing | 2065 | * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing |
2050 | * it to fail all oustanding SCSI IO. | 2066 | * it to fail all oustanding SCSI IO. |
2051 | */ | 2067 | */ |
2052 | phba->hba_state = LPFC_STATE_UNKNOWN; | 2068 | spin_lock_irq(&phba->pport->work_port_lock); |
2053 | phba->work_hba_events &= ~WORKER_MBOX_TMO; | 2069 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; |
2054 | phba->fc_flag |= FC_ESTABLISH_LINK; | 2070 | spin_unlock_irq(&phba->pport->work_port_lock); |
2071 | spin_lock_irq(&phba->hbalock); | ||
2072 | phba->link_state = LPFC_LINK_UNKNOWN; | ||
2073 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; | ||
2055 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 2074 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
2056 | spin_unlock_irq(phba->host->host_lock); | 2075 | spin_unlock_irq(&phba->hbalock); |
2057 | 2076 | ||
2058 | pring = &psli->ring[psli->fcp_ring]; | 2077 | pring = &psli->ring[psli->fcp_ring]; |
2059 | lpfc_sli_abort_iocb_ring(phba, pring); | 2078 | lpfc_sli_abort_iocb_ring(phba, pring); |
@@ -2075,10 +2094,10 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2075 | } | 2094 | } |
2076 | 2095 | ||
2077 | int | 2096 | int |
2078 | lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | 2097 | lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) |
2079 | { | 2098 | { |
2080 | MAILBOX_t *mb; | 2099 | MAILBOX_t *mb; |
2081 | struct lpfc_sli *psli; | 2100 | struct lpfc_sli *psli = &phba->sli; |
2082 | uint32_t status, evtctr; | 2101 | uint32_t status, evtctr; |
2083 | uint32_t ha_copy; | 2102 | uint32_t ha_copy; |
2084 | int i; | 2103 | int i; |
@@ -2090,27 +2109,25 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2090 | if (unlikely(pci_channel_offline(phba->pcidev))) | 2109 | if (unlikely(pci_channel_offline(phba->pcidev))) |
2091 | return MBX_NOT_FINISHED; | 2110 | return MBX_NOT_FINISHED; |
2092 | 2111 | ||
2112 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | ||
2093 | psli = &phba->sli; | 2113 | psli = &phba->sli; |
2094 | 2114 | ||
2095 | spin_lock_irqsave(phba->host->host_lock, drvr_flag); | ||
2096 | |||
2097 | |||
2098 | mb = &pmbox->mb; | 2115 | mb = &pmbox->mb; |
2099 | status = MBX_SUCCESS; | 2116 | status = MBX_SUCCESS; |
2100 | 2117 | ||
2101 | if (phba->hba_state == LPFC_HBA_ERROR) { | 2118 | if (phba->link_state == LPFC_HBA_ERROR) { |
2102 | spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); | 2119 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2103 | 2120 | ||
2104 | /* Mbox command <mbxCommand> cannot issue */ | 2121 | /* Mbox command <mbxCommand> cannot issue */ |
2105 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) | 2122 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) |
2106 | return (MBX_NOT_FINISHED); | 2123 | return MBX_NOT_FINISHED; |
2107 | } | 2124 | } |
2108 | 2125 | ||
2109 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && | 2126 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && |
2110 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { | 2127 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { |
2111 | spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); | 2128 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2112 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) | 2129 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) |
2113 | return (MBX_NOT_FINISHED); | 2130 | return MBX_NOT_FINISHED; |
2114 | } | 2131 | } |
2115 | 2132 | ||
2116 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { | 2133 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { |
@@ -2120,20 +2137,18 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2120 | */ | 2137 | */ |
2121 | 2138 | ||
2122 | if (flag & MBX_POLL) { | 2139 | if (flag & MBX_POLL) { |
2123 | spin_unlock_irqrestore(phba->host->host_lock, | 2140 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2124 | drvr_flag); | ||
2125 | 2141 | ||
2126 | /* Mbox command <mbxCommand> cannot issue */ | 2142 | /* Mbox command <mbxCommand> cannot issue */ |
2127 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) | 2143 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, mb, psli, flag); |
2128 | return (MBX_NOT_FINISHED); | 2144 | return MBX_NOT_FINISHED; |
2129 | } | 2145 | } |
2130 | 2146 | ||
2131 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { | 2147 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { |
2132 | spin_unlock_irqrestore(phba->host->host_lock, | 2148 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2133 | drvr_flag); | ||
2134 | /* Mbox command <mbxCommand> cannot issue */ | 2149 | /* Mbox command <mbxCommand> cannot issue */ |
2135 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) | 2150 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, mb, psli, flag); |
2136 | return (MBX_NOT_FINISHED); | 2151 | return MBX_NOT_FINISHED; |
2137 | } | 2152 | } |
2138 | 2153 | ||
2139 | /* Handle STOP IOCB processing flag. This is only meaningful | 2154 | /* Handle STOP IOCB processing flag. This is only meaningful |
@@ -2163,15 +2178,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2163 | "%d:0308 Mbox cmd issue - BUSY Data: x%x x%x x%x x%x\n", | 2178 | "%d:0308 Mbox cmd issue - BUSY Data: x%x x%x x%x x%x\n", |
2164 | phba->brd_no, | 2179 | phba->brd_no, |
2165 | mb->mbxCommand, | 2180 | mb->mbxCommand, |
2166 | phba->hba_state, | 2181 | phba->pport->port_state, |
2167 | psli->sli_flag, | 2182 | psli->sli_flag, |
2168 | flag); | 2183 | flag); |
2169 | 2184 | ||
2170 | psli->slistat.mbox_busy++; | 2185 | psli->slistat.mbox_busy++; |
2171 | spin_unlock_irqrestore(phba->host->host_lock, | 2186 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2172 | drvr_flag); | ||
2173 | 2187 | ||
2174 | return (MBX_BUSY); | 2188 | return MBX_BUSY; |
2175 | } | 2189 | } |
2176 | 2190 | ||
2177 | /* Handle STOP IOCB processing flag. This is only meaningful | 2191 | /* Handle STOP IOCB processing flag. This is only meaningful |
@@ -2198,11 +2212,10 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2198 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE) && | 2212 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE) && |
2199 | (mb->mbxCommand != MBX_KILL_BOARD)) { | 2213 | (mb->mbxCommand != MBX_KILL_BOARD)) { |
2200 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2214 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2201 | spin_unlock_irqrestore(phba->host->host_lock, | 2215 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2202 | drvr_flag); | ||
2203 | /* Mbox command <mbxCommand> cannot issue */ | 2216 | /* Mbox command <mbxCommand> cannot issue */ |
2204 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag); | 2217 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag); |
2205 | return (MBX_NOT_FINISHED); | 2218 | return MBX_NOT_FINISHED; |
2206 | } | 2219 | } |
2207 | /* timeout active mbox command */ | 2220 | /* timeout active mbox command */ |
2208 | mod_timer(&psli->mbox_tmo, (jiffies + | 2221 | mod_timer(&psli->mbox_tmo, (jiffies + |
@@ -2216,9 +2229,9 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2216 | "%d:0309 Mailbox cmd x%x issue Data: x%x x%x x%x\n", | 2229 | "%d:0309 Mailbox cmd x%x issue Data: x%x x%x x%x\n", |
2217 | phba->brd_no, | 2230 | phba->brd_no, |
2218 | mb->mbxCommand, | 2231 | mb->mbxCommand, |
2219 | phba->hba_state, | 2232 | phba->pport->port_state, |
2220 | psli->sli_flag, | 2233 | psli->sli_flag, |
2221 | flag); | 2234 | flag); |
2222 | 2235 | ||
2223 | psli->slistat.mbox_cmd++; | 2236 | psli->slistat.mbox_cmd++; |
2224 | evtctr = psli->slistat.mbox_event; | 2237 | evtctr = psli->slistat.mbox_event; |
@@ -2285,12 +2298,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2285 | /* Wait for command to complete */ | 2298 | /* Wait for command to complete */ |
2286 | while (((word0 & OWN_CHIP) == OWN_CHIP) || | 2299 | while (((word0 & OWN_CHIP) == OWN_CHIP) || |
2287 | (!(ha_copy & HA_MBATT) && | 2300 | (!(ha_copy & HA_MBATT) && |
2288 | (phba->hba_state > LPFC_WARM_START))) { | 2301 | (phba->link_state > LPFC_WARM_START))) { |
2289 | if (i-- <= 0) { | 2302 | if (i-- <= 0) { |
2290 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2303 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2291 | spin_unlock_irqrestore(phba->host->host_lock, | 2304 | spin_unlock_irqrestore(&phba->hbalock, |
2292 | drvr_flag); | 2305 | drvr_flag); |
2293 | return (MBX_NOT_FINISHED); | 2306 | return MBX_NOT_FINISHED; |
2294 | } | 2307 | } |
2295 | 2308 | ||
2296 | /* Check if we took a mbox interrupt while we were | 2309 | /* Check if we took a mbox interrupt while we were |
@@ -2299,12 +2312,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2299 | && (evtctr != psli->slistat.mbox_event)) | 2312 | && (evtctr != psli->slistat.mbox_event)) |
2300 | break; | 2313 | break; |
2301 | 2314 | ||
2302 | spin_unlock_irqrestore(phba->host->host_lock, | 2315 | spin_unlock_irqrestore(&phba->hbalock, |
2303 | drvr_flag); | 2316 | drvr_flag); |
2304 | 2317 | ||
2305 | msleep(1); | 2318 | msleep(1); |
2306 | 2319 | ||
2307 | spin_lock_irqsave(phba->host->host_lock, drvr_flag); | 2320 | spin_lock_irqsave(&phba->hbalock, drvr_flag); |
2308 | 2321 | ||
2309 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { | 2322 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { |
2310 | /* First copy command data */ | 2323 | /* First copy command data */ |
@@ -2342,7 +2355,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2342 | MAILBOX_CMD_SIZE); | 2355 | MAILBOX_CMD_SIZE); |
2343 | if ((mb->mbxCommand == MBX_DUMP_MEMORY) && | 2356 | if ((mb->mbxCommand == MBX_DUMP_MEMORY) && |
2344 | pmbox->context2) { | 2357 | pmbox->context2) { |
2345 | lpfc_memcpy_from_slim((void *)pmbox->context2, | 2358 | lpfc_memcpy_from_slim((void *) pmbox->context2, |
2346 | phba->MBslimaddr + DMP_RSP_OFFSET, | 2359 | phba->MBslimaddr + DMP_RSP_OFFSET, |
2347 | mb->un.varDmp.word_cnt); | 2360 | mb->un.varDmp.word_cnt); |
2348 | } | 2361 | } |
@@ -2355,23 +2368,27 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2355 | status = mb->mbxStatus; | 2368 | status = mb->mbxStatus; |
2356 | } | 2369 | } |
2357 | 2370 | ||
2358 | spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); | 2371 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2359 | return (status); | 2372 | return status; |
2360 | } | 2373 | } |
2361 | 2374 | ||
2362 | static int | 2375 | static int |
2363 | lpfc_sli_ringtx_put(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, | 2376 | lpfc_sli_ringtx_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
2364 | struct lpfc_iocbq * piocb) | 2377 | struct lpfc_iocbq *piocb) |
2365 | { | 2378 | { |
2379 | unsigned long iflags; | ||
2380 | |||
2366 | /* Insert the caller's iocb in the txq tail for later processing. */ | 2381 | /* Insert the caller's iocb in the txq tail for later processing. */ |
2382 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
2367 | list_add_tail(&piocb->list, &pring->txq); | 2383 | list_add_tail(&piocb->list, &pring->txq); |
2368 | pring->txq_cnt++; | 2384 | pring->txq_cnt++; |
2369 | return (0); | 2385 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
2386 | return 0; | ||
2370 | } | 2387 | } |
2371 | 2388 | ||
2372 | static struct lpfc_iocbq * | 2389 | static struct lpfc_iocbq * |
2373 | lpfc_sli_next_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 2390 | lpfc_sli_next_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
2374 | struct lpfc_iocbq ** piocb) | 2391 | struct lpfc_iocbq **piocb) |
2375 | { | 2392 | { |
2376 | struct lpfc_iocbq * nextiocb; | 2393 | struct lpfc_iocbq * nextiocb; |
2377 | 2394 | ||
@@ -2389,6 +2406,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2389 | struct lpfc_iocbq *piocb, uint32_t flag) | 2406 | struct lpfc_iocbq *piocb, uint32_t flag) |
2390 | { | 2407 | { |
2391 | struct lpfc_iocbq *nextiocb; | 2408 | struct lpfc_iocbq *nextiocb; |
2409 | unsigned long iflags; | ||
2392 | IOCB_t *iocb; | 2410 | IOCB_t *iocb; |
2393 | 2411 | ||
2394 | /* If the PCI channel is in offline state, do not post iocbs. */ | 2412 | /* If the PCI channel is in offline state, do not post iocbs. */ |
@@ -2398,7 +2416,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2398 | /* | 2416 | /* |
2399 | * We should never get an IOCB if we are in a < LINK_DOWN state | 2417 | * We should never get an IOCB if we are in a < LINK_DOWN state |
2400 | */ | 2418 | */ |
2401 | if (unlikely(phba->hba_state < LPFC_LINK_DOWN)) | 2419 | if (unlikely(phba->link_state < LPFC_LINK_DOWN)) |
2402 | return IOCB_ERROR; | 2420 | return IOCB_ERROR; |
2403 | 2421 | ||
2404 | /* | 2422 | /* |
@@ -2408,7 +2426,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2408 | if (unlikely(pring->flag & LPFC_STOP_IOCB_MBX)) | 2426 | if (unlikely(pring->flag & LPFC_STOP_IOCB_MBX)) |
2409 | goto iocb_busy; | 2427 | goto iocb_busy; |
2410 | 2428 | ||
2411 | if (unlikely(phba->hba_state == LPFC_LINK_DOWN)) { | 2429 | if (unlikely(phba->link_state == LPFC_LINK_DOWN)) { |
2412 | /* | 2430 | /* |
2413 | * Only CREATE_XRI, CLOSE_XRI, and QUE_RING_BUF | 2431 | * Only CREATE_XRI, CLOSE_XRI, and QUE_RING_BUF |
2414 | * can be issued if the link is not up. | 2432 | * can be issued if the link is not up. |
@@ -2439,6 +2457,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2439 | !(phba->sli.sli_flag & LPFC_PROCESS_LA))) | 2457 | !(phba->sli.sli_flag & LPFC_PROCESS_LA))) |
2440 | goto iocb_busy; | 2458 | goto iocb_busy; |
2441 | 2459 | ||
2460 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
2442 | while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) && | 2461 | while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) && |
2443 | (nextiocb = lpfc_sli_next_iocb(phba, pring, &piocb))) | 2462 | (nextiocb = lpfc_sli_next_iocb(phba, pring, &piocb))) |
2444 | lpfc_sli_submit_iocb(phba, pring, iocb, nextiocb); | 2463 | lpfc_sli_submit_iocb(phba, pring, iocb, nextiocb); |
@@ -2447,6 +2466,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2447 | lpfc_sli_update_ring(phba, pring); | 2466 | lpfc_sli_update_ring(phba, pring); |
2448 | else | 2467 | else |
2449 | lpfc_sli_update_full_ring(phba, pring); | 2468 | lpfc_sli_update_full_ring(phba, pring); |
2469 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
2450 | 2470 | ||
2451 | if (!piocb) | 2471 | if (!piocb) |
2452 | return IOCB_SUCCESS; | 2472 | return IOCB_SUCCESS; |
@@ -2454,7 +2474,9 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2454 | goto out_busy; | 2474 | goto out_busy; |
2455 | 2475 | ||
2456 | iocb_busy: | 2476 | iocb_busy: |
2477 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
2457 | pring->stats.iocb_cmd_delay++; | 2478 | pring->stats.iocb_cmd_delay++; |
2479 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
2458 | 2480 | ||
2459 | out_busy: | 2481 | out_busy: |
2460 | 2482 | ||
@@ -2539,6 +2561,7 @@ lpfc_sli_setup(struct lpfc_hba *phba) | |||
2539 | /* numCiocb and numRiocb are used in config_port */ | 2561 | /* numCiocb and numRiocb are used in config_port */ |
2540 | pring->numCiocb = SLI2_IOCB_CMD_R1_ENTRIES; | 2562 | pring->numCiocb = SLI2_IOCB_CMD_R1_ENTRIES; |
2541 | pring->numRiocb = SLI2_IOCB_RSP_R1_ENTRIES; | 2563 | pring->numRiocb = SLI2_IOCB_RSP_R1_ENTRIES; |
2564 | pring->iotag_max = phba->cfg_hba_queue_depth; | ||
2542 | pring->num_mask = 0; | 2565 | pring->num_mask = 0; |
2543 | break; | 2566 | break; |
2544 | case LPFC_ELS_RING: /* ring 2 - ELS / CT */ | 2567 | case LPFC_ELS_RING: /* ring 2 - ELS / CT */ |
@@ -2591,14 +2614,14 @@ lpfc_sli_setup(struct lpfc_hba *phba) | |||
2591 | } | 2614 | } |
2592 | 2615 | ||
2593 | int | 2616 | int |
2594 | lpfc_sli_queue_setup(struct lpfc_hba * phba) | 2617 | lpfc_sli_queue_setup(struct lpfc_hba *phba) |
2595 | { | 2618 | { |
2596 | struct lpfc_sli *psli; | 2619 | struct lpfc_sli *psli; |
2597 | struct lpfc_sli_ring *pring; | 2620 | struct lpfc_sli_ring *pring; |
2598 | int i; | 2621 | int i; |
2599 | 2622 | ||
2600 | psli = &phba->sli; | 2623 | psli = &phba->sli; |
2601 | spin_lock_irq(phba->host->host_lock); | 2624 | spin_lock_irq(&phba->hbalock); |
2602 | INIT_LIST_HEAD(&psli->mboxq); | 2625 | INIT_LIST_HEAD(&psli->mboxq); |
2603 | /* Initialize list headers for txq and txcmplq as double linked lists */ | 2626 | /* Initialize list headers for txq and txcmplq as double linked lists */ |
2604 | for (i = 0; i < psli->num_rings; i++) { | 2627 | for (i = 0; i < psli->num_rings; i++) { |
@@ -2612,15 +2635,15 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba) | |||
2612 | INIT_LIST_HEAD(&pring->iocb_continueq); | 2635 | INIT_LIST_HEAD(&pring->iocb_continueq); |
2613 | INIT_LIST_HEAD(&pring->postbufq); | 2636 | INIT_LIST_HEAD(&pring->postbufq); |
2614 | } | 2637 | } |
2615 | spin_unlock_irq(phba->host->host_lock); | 2638 | spin_unlock_irq(&phba->hbalock); |
2616 | return (1); | 2639 | return 1; |
2617 | } | 2640 | } |
2618 | 2641 | ||
2619 | int | 2642 | int |
2620 | lpfc_sli_hba_down(struct lpfc_hba * phba) | 2643 | lpfc_sli_hba_down(struct lpfc_hba *phba) |
2621 | { | 2644 | { |
2622 | LIST_HEAD(completions); | 2645 | LIST_HEAD(completions); |
2623 | struct lpfc_sli *psli; | 2646 | struct lpfc_sli *psli = &phba->sli; |
2624 | struct lpfc_sli_ring *pring; | 2647 | struct lpfc_sli_ring *pring; |
2625 | LPFC_MBOXQ_t *pmb; | 2648 | LPFC_MBOXQ_t *pmb; |
2626 | struct lpfc_iocbq *iocb; | 2649 | struct lpfc_iocbq *iocb; |
@@ -2628,10 +2651,9 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) | |||
2628 | int i; | 2651 | int i; |
2629 | unsigned long flags = 0; | 2652 | unsigned long flags = 0; |
2630 | 2653 | ||
2631 | psli = &phba->sli; | ||
2632 | lpfc_hba_down_prep(phba); | 2654 | lpfc_hba_down_prep(phba); |
2633 | 2655 | ||
2634 | spin_lock_irqsave(phba->host->host_lock, flags); | 2656 | spin_lock_irqsave(&phba->hbalock, flags); |
2635 | for (i = 0; i < psli->num_rings; i++) { | 2657 | for (i = 0; i < psli->num_rings; i++) { |
2636 | pring = &psli->ring[i]; | 2658 | pring = &psli->ring[i]; |
2637 | pring->flag |= LPFC_DEFERRED_RING_EVENT; | 2659 | pring->flag |= LPFC_DEFERRED_RING_EVENT; |
@@ -2644,51 +2666,48 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) | |||
2644 | pring->txq_cnt = 0; | 2666 | pring->txq_cnt = 0; |
2645 | 2667 | ||
2646 | } | 2668 | } |
2647 | spin_unlock_irqrestore(phba->host->host_lock, flags); | 2669 | spin_unlock_irqrestore(&phba->hbalock, flags); |
2648 | 2670 | ||
2649 | while (!list_empty(&completions)) { | 2671 | while (!list_empty(&completions)) { |
2650 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | 2672 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); |
2651 | cmd = &iocb->iocb; | 2673 | cmd = &iocb->iocb; |
2652 | list_del(&iocb->list); | 2674 | list_del(&iocb->list); |
2653 | 2675 | ||
2654 | if (iocb->iocb_cmpl) { | 2676 | if (!iocb->iocb_cmpl) |
2677 | lpfc_sli_release_iocbq(phba, iocb); | ||
2678 | else { | ||
2655 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 2679 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
2656 | cmd->un.ulpWord[4] = IOERR_SLI_DOWN; | 2680 | cmd->un.ulpWord[4] = IOERR_SLI_DOWN; |
2657 | (iocb->iocb_cmpl) (phba, iocb, iocb); | 2681 | (iocb->iocb_cmpl) (phba, iocb, iocb); |
2658 | } else | 2682 | } |
2659 | lpfc_sli_release_iocbq(phba, iocb); | ||
2660 | } | 2683 | } |
2661 | 2684 | ||
2662 | /* Return any active mbox cmds */ | 2685 | /* Return any active mbox cmds */ |
2663 | del_timer_sync(&psli->mbox_tmo); | 2686 | del_timer_sync(&psli->mbox_tmo); |
2664 | spin_lock_irqsave(phba->host->host_lock, flags); | 2687 | |
2665 | phba->work_hba_events &= ~WORKER_MBOX_TMO; | 2688 | spin_lock_irqsave(&phba->pport->work_port_lock, flags); |
2666 | if (psli->mbox_active) { | 2689 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; |
2667 | pmb = psli->mbox_active; | 2690 | spin_unlock_irqrestore(&phba->pport->work_port_lock, flags); |
2691 | |||
2692 | pmb = psli->mbox_active; | ||
2693 | if (pmb) { | ||
2694 | psli->mbox_active = NULL; | ||
2668 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; | 2695 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; |
2696 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
2669 | if (pmb->mbox_cmpl) { | 2697 | if (pmb->mbox_cmpl) { |
2670 | spin_unlock_irqrestore(phba->host->host_lock, flags); | ||
2671 | pmb->mbox_cmpl(phba,pmb); | 2698 | pmb->mbox_cmpl(phba,pmb); |
2672 | spin_lock_irqsave(phba->host->host_lock, flags); | ||
2673 | } | 2699 | } |
2674 | } | 2700 | } |
2675 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
2676 | psli->mbox_active = NULL; | ||
2677 | 2701 | ||
2678 | /* Return any pending mbox cmds */ | 2702 | /* Return any pending mbox cmds */ |
2679 | while ((pmb = lpfc_mbox_get(phba)) != NULL) { | 2703 | while ((pmb = lpfc_mbox_get(phba)) != NULL) { |
2680 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; | 2704 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; |
2681 | if (pmb->mbox_cmpl) { | 2705 | if (pmb->mbox_cmpl) { |
2682 | spin_unlock_irqrestore(phba->host->host_lock, flags); | ||
2683 | pmb->mbox_cmpl(phba,pmb); | 2706 | pmb->mbox_cmpl(phba,pmb); |
2684 | spin_lock_irqsave(phba->host->host_lock, flags); | ||
2685 | } | 2707 | } |
2686 | } | 2708 | } |
2687 | |||
2688 | INIT_LIST_HEAD(&psli->mboxq); | 2709 | INIT_LIST_HEAD(&psli->mboxq); |
2689 | 2710 | ||
2690 | spin_unlock_irqrestore(phba->host->host_lock, flags); | ||
2691 | |||
2692 | return 1; | 2711 | return 1; |
2693 | } | 2712 | } |
2694 | 2713 | ||
@@ -2710,14 +2729,15 @@ lpfc_sli_pcimem_bcopy(void *srcp, void *destp, uint32_t cnt) | |||
2710 | } | 2729 | } |
2711 | 2730 | ||
2712 | int | 2731 | int |
2713 | lpfc_sli_ringpostbuf_put(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, | 2732 | lpfc_sli_ringpostbuf_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
2714 | struct lpfc_dmabuf * mp) | 2733 | struct lpfc_dmabuf *mp) |
2715 | { | 2734 | { |
2716 | /* Stick struct lpfc_dmabuf at end of postbufq so driver can look it up | 2735 | /* Stick struct lpfc_dmabuf at end of postbufq so driver can look it up |
2717 | later */ | 2736 | later */ |
2737 | spin_lock_irq(&phba->hbalock); | ||
2718 | list_add_tail(&mp->list, &pring->postbufq); | 2738 | list_add_tail(&mp->list, &pring->postbufq); |
2719 | |||
2720 | pring->postbufq_cnt++; | 2739 | pring->postbufq_cnt++; |
2740 | spin_unlock_irq(&phba->hbalock); | ||
2721 | return 0; | 2741 | return 0; |
2722 | } | 2742 | } |
2723 | 2743 | ||
@@ -2730,40 +2750,41 @@ lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2730 | struct list_head *slp = &pring->postbufq; | 2750 | struct list_head *slp = &pring->postbufq; |
2731 | 2751 | ||
2732 | /* Search postbufq, from the begining, looking for a match on phys */ | 2752 | /* Search postbufq, from the begining, looking for a match on phys */ |
2753 | spin_lock_irq(&phba->hbalock); | ||
2733 | list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { | 2754 | list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { |
2734 | if (mp->phys == phys) { | 2755 | if (mp->phys == phys) { |
2735 | list_del_init(&mp->list); | 2756 | list_del_init(&mp->list); |
2736 | pring->postbufq_cnt--; | 2757 | pring->postbufq_cnt--; |
2758 | spin_unlock_irq(&phba->hbalock); | ||
2737 | return mp; | 2759 | return mp; |
2738 | } | 2760 | } |
2739 | } | 2761 | } |
2740 | 2762 | ||
2763 | spin_unlock_irq(&phba->hbalock); | ||
2741 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2764 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2742 | "%d:0410 Cannot find virtual addr for mapped buf on " | 2765 | "%d:0410 Cannot find virtual addr for mapped buf on " |
2743 | "ring %d Data x%llx x%p x%p x%x\n", | 2766 | "ring %d Data x%llx x%p x%p x%x\n", |
2744 | phba->brd_no, pring->ringno, (unsigned long long)phys, | 2767 | phba->brd_no, pring->ringno, (unsigned long long) phys, |
2745 | slp->next, slp->prev, pring->postbufq_cnt); | 2768 | slp->next, slp->prev, pring->postbufq_cnt); |
2746 | return NULL; | 2769 | return NULL; |
2747 | } | 2770 | } |
2748 | 2771 | ||
2749 | static void | 2772 | static void |
2750 | lpfc_sli_abort_els_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2773 | lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
2751 | struct lpfc_iocbq * rspiocb) | 2774 | struct lpfc_iocbq *rspiocb) |
2752 | { | 2775 | { |
2753 | IOCB_t *irsp; | 2776 | IOCB_t *irsp = &rspiocb->iocb; |
2754 | uint16_t abort_iotag, abort_context; | 2777 | uint16_t abort_iotag, abort_context; |
2755 | struct lpfc_iocbq *abort_iocb, *rsp_ab_iocb; | 2778 | struct lpfc_iocbq *abort_iocb, *rsp_ab_iocb; |
2756 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; | 2779 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; |
2757 | 2780 | ||
2758 | abort_iocb = NULL; | 2781 | abort_iocb = NULL; |
2759 | irsp = &rspiocb->iocb; | ||
2760 | |||
2761 | spin_lock_irq(phba->host->host_lock); | ||
2762 | 2782 | ||
2763 | if (irsp->ulpStatus) { | 2783 | if (irsp->ulpStatus) { |
2764 | abort_context = cmdiocb->iocb.un.acxri.abortContextTag; | 2784 | abort_context = cmdiocb->iocb.un.acxri.abortContextTag; |
2765 | abort_iotag = cmdiocb->iocb.un.acxri.abortIoTag; | 2785 | abort_iotag = cmdiocb->iocb.un.acxri.abortIoTag; |
2766 | 2786 | ||
2787 | spin_lock_irq(&phba->hbalock); | ||
2767 | if (abort_iotag != 0 && abort_iotag <= phba->sli.last_iotag) | 2788 | if (abort_iotag != 0 && abort_iotag <= phba->sli.last_iotag) |
2768 | abort_iocb = phba->sli.iocbq_lookup[abort_iotag]; | 2789 | abort_iocb = phba->sli.iocbq_lookup[abort_iotag]; |
2769 | 2790 | ||
@@ -2777,41 +2798,40 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
2777 | * make sure we have the right iocbq before taking it | 2798 | * make sure we have the right iocbq before taking it |
2778 | * off the txcmplq and try to call completion routine. | 2799 | * off the txcmplq and try to call completion routine. |
2779 | */ | 2800 | */ |
2780 | if (abort_iocb && | 2801 | if (!abort_iocb || |
2781 | abort_iocb->iocb.ulpContext == abort_context && | 2802 | abort_iocb->iocb.ulpContext != abort_context || |
2782 | abort_iocb->iocb_flag & LPFC_DRIVER_ABORTED) { | 2803 | (abort_iocb->iocb_flag & LPFC_DRIVER_ABORTED) == 0) |
2804 | spin_unlock_irq(&phba->hbalock); | ||
2805 | else { | ||
2783 | list_del(&abort_iocb->list); | 2806 | list_del(&abort_iocb->list); |
2784 | pring->txcmplq_cnt--; | 2807 | pring->txcmplq_cnt--; |
2808 | spin_unlock_irq(&phba->hbalock); | ||
2785 | 2809 | ||
2786 | rsp_ab_iocb = lpfc_sli_get_iocbq(phba); | 2810 | rsp_ab_iocb = lpfc_sli_get_iocbq(phba); |
2787 | if (rsp_ab_iocb == NULL) | 2811 | if (rsp_ab_iocb == NULL) |
2788 | lpfc_sli_release_iocbq(phba, abort_iocb); | 2812 | lpfc_sli_release_iocbq(phba, abort_iocb); |
2789 | else { | 2813 | else { |
2790 | abort_iocb->iocb_flag &= | 2814 | abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED; |
2791 | ~LPFC_DRIVER_ABORTED; | ||
2792 | rsp_ab_iocb->iocb.ulpStatus = | 2815 | rsp_ab_iocb->iocb.ulpStatus = |
2793 | IOSTAT_LOCAL_REJECT; | 2816 | IOSTAT_LOCAL_REJECT; |
2794 | rsp_ab_iocb->iocb.un.ulpWord[4] = | 2817 | rsp_ab_iocb->iocb.un.ulpWord[4] = |
2795 | IOERR_SLI_ABORTED; | 2818 | IOERR_SLI_ABORTED; |
2796 | spin_unlock_irq(phba->host->host_lock); | 2819 | (abort_iocb->iocb_cmpl)(phba, abort_iocb, |
2797 | (abort_iocb->iocb_cmpl) | 2820 | rsp_ab_iocb); |
2798 | (phba, abort_iocb, rsp_ab_iocb); | ||
2799 | spin_lock_irq(phba->host->host_lock); | ||
2800 | lpfc_sli_release_iocbq(phba, rsp_ab_iocb); | 2821 | lpfc_sli_release_iocbq(phba, rsp_ab_iocb); |
2801 | } | 2822 | } |
2802 | } | 2823 | } |
2803 | } | 2824 | } |
2804 | 2825 | ||
2805 | lpfc_sli_release_iocbq(phba, cmdiocb); | 2826 | lpfc_sli_release_iocbq(phba, cmdiocb); |
2806 | spin_unlock_irq(phba->host->host_lock); | ||
2807 | return; | 2827 | return; |
2808 | } | 2828 | } |
2809 | 2829 | ||
2810 | int | 2830 | int |
2811 | lpfc_sli_issue_abort_iotag(struct lpfc_hba * phba, | 2831 | lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
2812 | struct lpfc_sli_ring * pring, | 2832 | struct lpfc_iocbq *cmdiocb) |
2813 | struct lpfc_iocbq * cmdiocb) | ||
2814 | { | 2833 | { |
2834 | struct lpfc_vport *vport = cmdiocb->vport; | ||
2815 | struct lpfc_iocbq *abtsiocbp; | 2835 | struct lpfc_iocbq *abtsiocbp; |
2816 | IOCB_t *icmd = NULL; | 2836 | IOCB_t *icmd = NULL; |
2817 | IOCB_t *iabt = NULL; | 2837 | IOCB_t *iabt = NULL; |
@@ -2821,14 +2841,14 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba * phba, | |||
2821 | * to abort. | 2841 | * to abort. |
2822 | */ | 2842 | */ |
2823 | icmd = &cmdiocb->iocb; | 2843 | icmd = &cmdiocb->iocb; |
2824 | if ((icmd->ulpCommand == CMD_ABORT_XRI_CN) || | 2844 | if (icmd->ulpCommand == CMD_ABORT_XRI_CN || |
2825 | (icmd->ulpCommand == CMD_CLOSE_XRI_CN)) | 2845 | icmd->ulpCommand == CMD_CLOSE_XRI_CN) |
2826 | return 0; | 2846 | return 0; |
2827 | 2847 | ||
2828 | /* If we're unloading, interrupts are disabled so we | 2848 | /* If we're unloading, interrupts are disabled so we |
2829 | * need to cleanup the iocb here. | 2849 | * need to cleanup the iocb here. |
2830 | */ | 2850 | */ |
2831 | if (phba->fc_flag & FC_UNLOADING) | 2851 | if (vport->load_flag & FC_UNLOADING) |
2832 | goto abort_iotag_exit; | 2852 | goto abort_iotag_exit; |
2833 | 2853 | ||
2834 | /* issue ABTS for this IOCB based on iotag */ | 2854 | /* issue ABTS for this IOCB based on iotag */ |
@@ -2848,7 +2868,7 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba * phba, | |||
2848 | iabt->ulpLe = 1; | 2868 | iabt->ulpLe = 1; |
2849 | iabt->ulpClass = icmd->ulpClass; | 2869 | iabt->ulpClass = icmd->ulpClass; |
2850 | 2870 | ||
2851 | if (phba->hba_state >= LPFC_LINK_UP) | 2871 | if (phba->link_state >= LPFC_LINK_UP) |
2852 | iabt->ulpCommand = CMD_ABORT_XRI_CN; | 2872 | iabt->ulpCommand = CMD_ABORT_XRI_CN; |
2853 | else | 2873 | else |
2854 | iabt->ulpCommand = CMD_CLOSE_XRI_CN; | 2874 | iabt->ulpCommand = CMD_CLOSE_XRI_CN; |
@@ -2863,25 +2883,12 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba * phba, | |||
2863 | retval = lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0); | 2883 | retval = lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0); |
2864 | 2884 | ||
2865 | abort_iotag_exit: | 2885 | abort_iotag_exit: |
2866 | 2886 | /* | |
2867 | /* If we could not issue an abort dequeue the iocb and handle | 2887 | * Caller to this routine should check for IOCB_ERROR |
2868 | * the completion here. | 2888 | * and handle it properly. This routine no longer removes |
2889 | * iocb off txcmplq and call compl in case of IOCB_ERROR. | ||
2869 | */ | 2890 | */ |
2870 | if (retval == IOCB_ERROR) { | 2891 | return retval; |
2871 | list_del(&cmdiocb->list); | ||
2872 | pring->txcmplq_cnt--; | ||
2873 | |||
2874 | if (cmdiocb->iocb_cmpl) { | ||
2875 | icmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
2876 | icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
2877 | spin_unlock_irq(phba->host->host_lock); | ||
2878 | (cmdiocb->iocb_cmpl) (phba, cmdiocb, cmdiocb); | ||
2879 | spin_lock_irq(phba->host->host_lock); | ||
2880 | } else | ||
2881 | lpfc_sli_release_iocbq(phba, cmdiocb); | ||
2882 | } | ||
2883 | |||
2884 | return 1; | ||
2885 | } | 2892 | } |
2886 | 2893 | ||
2887 | static int | 2894 | static int |
@@ -2930,7 +2937,7 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id, | |||
2930 | 2937 | ||
2931 | int | 2938 | int |
2932 | lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 2939 | lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
2933 | uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd) | 2940 | uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd) |
2934 | { | 2941 | { |
2935 | struct lpfc_iocbq *iocbq; | 2942 | struct lpfc_iocbq *iocbq; |
2936 | int sum, i; | 2943 | int sum, i; |
@@ -2947,14 +2954,10 @@ lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2947 | } | 2954 | } |
2948 | 2955 | ||
2949 | void | 2956 | void |
2950 | lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2957 | lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
2951 | struct lpfc_iocbq * rspiocb) | 2958 | struct lpfc_iocbq *rspiocb) |
2952 | { | 2959 | { |
2953 | unsigned long iflags; | ||
2954 | |||
2955 | spin_lock_irqsave(phba->host->host_lock, iflags); | ||
2956 | lpfc_sli_release_iocbq(phba, cmdiocb); | 2960 | lpfc_sli_release_iocbq(phba, cmdiocb); |
2957 | spin_unlock_irqrestore(phba->host->host_lock, iflags); | ||
2958 | return; | 2961 | return; |
2959 | } | 2962 | } |
2960 | 2963 | ||
@@ -2972,8 +2975,8 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2972 | for (i = 1; i <= phba->sli.last_iotag; i++) { | 2975 | for (i = 1; i <= phba->sli.last_iotag; i++) { |
2973 | iocbq = phba->sli.iocbq_lookup[i]; | 2976 | iocbq = phba->sli.iocbq_lookup[i]; |
2974 | 2977 | ||
2975 | if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id, | 2978 | if (lpfc_sli_validate_fcp_iocb(iocbq, tgt_id, lun_id, 0, |
2976 | 0, abort_cmd) != 0) | 2979 | abort_cmd) != 0) |
2977 | continue; | 2980 | continue; |
2978 | 2981 | ||
2979 | /* issue ABTS for this IOCB based on iotag */ | 2982 | /* issue ABTS for this IOCB based on iotag */ |
@@ -2989,8 +2992,9 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2989 | abtsiocb->iocb.un.acxri.abortIoTag = cmd->ulpIoTag; | 2992 | abtsiocb->iocb.un.acxri.abortIoTag = cmd->ulpIoTag; |
2990 | abtsiocb->iocb.ulpLe = 1; | 2993 | abtsiocb->iocb.ulpLe = 1; |
2991 | abtsiocb->iocb.ulpClass = cmd->ulpClass; | 2994 | abtsiocb->iocb.ulpClass = cmd->ulpClass; |
2995 | abtsiocb->vport = phba->pport; | ||
2992 | 2996 | ||
2993 | if (phba->hba_state >= LPFC_LINK_UP) | 2997 | if (lpfc_is_link_up(phba)) |
2994 | abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN; | 2998 | abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN; |
2995 | else | 2999 | else |
2996 | abtsiocb->iocb.ulpCommand = CMD_CLOSE_XRI_CN; | 3000 | abtsiocb->iocb.ulpCommand = CMD_CLOSE_XRI_CN; |
@@ -3016,14 +3020,14 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, | |||
3016 | wait_queue_head_t *pdone_q; | 3020 | wait_queue_head_t *pdone_q; |
3017 | unsigned long iflags; | 3021 | unsigned long iflags; |
3018 | 3022 | ||
3019 | spin_lock_irqsave(phba->host->host_lock, iflags); | 3023 | spin_lock_irqsave(&phba->hbalock, iflags); |
3020 | cmdiocbq->iocb_flag |= LPFC_IO_WAKE; | 3024 | cmdiocbq->iocb_flag |= LPFC_IO_WAKE; |
3021 | if (cmdiocbq->context2 && rspiocbq) | 3025 | if (cmdiocbq->context2 && rspiocbq) |
3022 | memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, | 3026 | memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, |
3023 | &rspiocbq->iocb, sizeof(IOCB_t)); | 3027 | &rspiocbq->iocb, sizeof(IOCB_t)); |
3024 | 3028 | ||
3025 | pdone_q = cmdiocbq->context_un.wait_queue; | 3029 | pdone_q = cmdiocbq->context_un.wait_queue; |
3026 | spin_unlock_irqrestore(phba->host->host_lock, iflags); | 3030 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
3027 | if (pdone_q) | 3031 | if (pdone_q) |
3028 | wake_up(pdone_q); | 3032 | wake_up(pdone_q); |
3029 | return; | 3033 | return; |
@@ -3036,10 +3040,10 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, | |||
3036 | * definition this is a wait function. | 3040 | * definition this is a wait function. |
3037 | */ | 3041 | */ |
3038 | int | 3042 | int |
3039 | lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, | 3043 | lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba, |
3040 | struct lpfc_sli_ring * pring, | 3044 | struct lpfc_sli_ring *pring, |
3041 | struct lpfc_iocbq * piocb, | 3045 | struct lpfc_iocbq *piocb, |
3042 | struct lpfc_iocbq * prspiocbq, | 3046 | struct lpfc_iocbq *prspiocbq, |
3043 | uint32_t timeout) | 3047 | uint32_t timeout) |
3044 | { | 3048 | { |
3045 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); | 3049 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); |
@@ -3071,11 +3075,11 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, | |||
3071 | retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0); | 3075 | retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0); |
3072 | if (retval == IOCB_SUCCESS) { | 3076 | if (retval == IOCB_SUCCESS) { |
3073 | timeout_req = timeout * HZ; | 3077 | timeout_req = timeout * HZ; |
3074 | spin_unlock_irq(phba->host->host_lock); | 3078 | spin_unlock_irq(&phba->hbalock); |
3075 | timeleft = wait_event_timeout(done_q, | 3079 | timeleft = wait_event_timeout(done_q, |
3076 | piocb->iocb_flag & LPFC_IO_WAKE, | 3080 | piocb->iocb_flag & LPFC_IO_WAKE, |
3077 | timeout_req); | 3081 | timeout_req); |
3078 | spin_lock_irq(phba->host->host_lock); | 3082 | spin_lock_irq(&phba->hbalock); |
3079 | 3083 | ||
3080 | if (piocb->iocb_flag & LPFC_IO_WAKE) { | 3084 | if (piocb->iocb_flag & LPFC_IO_WAKE) { |
3081 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 3085 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
@@ -3117,7 +3121,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, | |||
3117 | } | 3121 | } |
3118 | 3122 | ||
3119 | int | 3123 | int |
3120 | lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | 3124 | lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, |
3121 | uint32_t timeout) | 3125 | uint32_t timeout) |
3122 | { | 3126 | { |
3123 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); | 3127 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); |
@@ -3125,7 +3129,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | |||
3125 | 3129 | ||
3126 | /* The caller must leave context1 empty. */ | 3130 | /* The caller must leave context1 empty. */ |
3127 | if (pmboxq->context1 != 0) { | 3131 | if (pmboxq->context1 != 0) { |
3128 | return (MBX_NOT_FINISHED); | 3132 | return MBX_NOT_FINISHED; |
3129 | } | 3133 | } |
3130 | 3134 | ||
3131 | /* setup wake call as IOCB callback */ | 3135 | /* setup wake call as IOCB callback */ |
@@ -3158,9 +3162,10 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | |||
3158 | int | 3162 | int |
3159 | lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba) | 3163 | lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba) |
3160 | { | 3164 | { |
3165 | struct lpfc_vport *vport = phba->pport; | ||
3161 | int i = 0; | 3166 | int i = 0; |
3162 | 3167 | ||
3163 | while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE && !phba->stopped) { | 3168 | while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE && !vport->stopped) { |
3164 | if (i++ > LPFC_MBOX_TMO * 1000) | 3169 | if (i++ > LPFC_MBOX_TMO * 1000) |
3165 | return 1; | 3170 | return 1; |
3166 | 3171 | ||
@@ -3176,7 +3181,7 @@ lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba) | |||
3176 | irqreturn_t | 3181 | irqreturn_t |
3177 | lpfc_intr_handler(int irq, void *dev_id) | 3182 | lpfc_intr_handler(int irq, void *dev_id) |
3178 | { | 3183 | { |
3179 | struct lpfc_hba *phba; | 3184 | struct lpfc_hba *phba; |
3180 | uint32_t ha_copy; | 3185 | uint32_t ha_copy; |
3181 | uint32_t work_ha_copy; | 3186 | uint32_t work_ha_copy; |
3182 | unsigned long status; | 3187 | unsigned long status; |
@@ -3204,7 +3209,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3204 | */ | 3209 | */ |
3205 | 3210 | ||
3206 | /* Ignore all interrupts during initialization. */ | 3211 | /* Ignore all interrupts during initialization. */ |
3207 | if (unlikely(phba->hba_state < LPFC_LINK_DOWN)) | 3212 | if (unlikely(phba->link_state < LPFC_LINK_DOWN)) |
3208 | return IRQ_NONE; | 3213 | return IRQ_NONE; |
3209 | 3214 | ||
3210 | /* | 3215 | /* |
@@ -3212,16 +3217,16 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3212 | * Clear Attention Sources, except Error Attention (to | 3217 | * Clear Attention Sources, except Error Attention (to |
3213 | * preserve status) and Link Attention | 3218 | * preserve status) and Link Attention |
3214 | */ | 3219 | */ |
3215 | spin_lock(phba->host->host_lock); | 3220 | spin_lock(&phba->hbalock); |
3216 | ha_copy = readl(phba->HAregaddr); | 3221 | ha_copy = readl(phba->HAregaddr); |
3217 | /* If somebody is waiting to handle an eratt don't process it | 3222 | /* If somebody is waiting to handle an eratt don't process it |
3218 | * here. The brdkill function will do this. | 3223 | * here. The brdkill function will do this. |
3219 | */ | 3224 | */ |
3220 | if (phba->fc_flag & FC_IGNORE_ERATT) | 3225 | if (phba->link_flag & LS_IGNORE_ERATT) |
3221 | ha_copy &= ~HA_ERATT; | 3226 | ha_copy &= ~HA_ERATT; |
3222 | writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr); | 3227 | writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr); |
3223 | readl(phba->HAregaddr); /* flush */ | 3228 | readl(phba->HAregaddr); /* flush */ |
3224 | spin_unlock(phba->host->host_lock); | 3229 | spin_unlock(&phba->hbalock); |
3225 | 3230 | ||
3226 | if (unlikely(!ha_copy)) | 3231 | if (unlikely(!ha_copy)) |
3227 | return IRQ_NONE; | 3232 | return IRQ_NONE; |
@@ -3235,13 +3240,13 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3235 | * Turn off Link Attention interrupts | 3240 | * Turn off Link Attention interrupts |
3236 | * until CLEAR_LA done | 3241 | * until CLEAR_LA done |
3237 | */ | 3242 | */ |
3238 | spin_lock(phba->host->host_lock); | 3243 | spin_lock(&phba->hbalock); |
3239 | phba->sli.sli_flag &= ~LPFC_PROCESS_LA; | 3244 | phba->sli.sli_flag &= ~LPFC_PROCESS_LA; |
3240 | control = readl(phba->HCregaddr); | 3245 | control = readl(phba->HCregaddr); |
3241 | control &= ~HC_LAINT_ENA; | 3246 | control &= ~HC_LAINT_ENA; |
3242 | writel(control, phba->HCregaddr); | 3247 | writel(control, phba->HCregaddr); |
3243 | readl(phba->HCregaddr); /* flush */ | 3248 | readl(phba->HCregaddr); /* flush */ |
3244 | spin_unlock(phba->host->host_lock); | 3249 | spin_unlock(&phba->hbalock); |
3245 | } | 3250 | } |
3246 | else | 3251 | else |
3247 | work_ha_copy &= ~HA_LATT; | 3252 | work_ha_copy &= ~HA_LATT; |
@@ -3253,18 +3258,18 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3253 | /* | 3258 | /* |
3254 | * Turn off Slow Rings interrupts | 3259 | * Turn off Slow Rings interrupts |
3255 | */ | 3260 | */ |
3256 | spin_lock(phba->host->host_lock); | 3261 | spin_lock(&phba->hbalock); |
3257 | control = readl(phba->HCregaddr); | 3262 | control = readl(phba->HCregaddr); |
3258 | control &= ~(HC_R0INT_ENA << i); | 3263 | control &= ~(HC_R0INT_ENA << i); |
3259 | writel(control, phba->HCregaddr); | 3264 | writel(control, phba->HCregaddr); |
3260 | readl(phba->HCregaddr); /* flush */ | 3265 | readl(phba->HCregaddr); /* flush */ |
3261 | spin_unlock(phba->host->host_lock); | 3266 | spin_unlock(&phba->hbalock); |
3262 | } | 3267 | } |
3263 | } | 3268 | } |
3264 | } | 3269 | } |
3265 | 3270 | ||
3266 | if (work_ha_copy & HA_ERATT) { | 3271 | if (work_ha_copy & HA_ERATT) { |
3267 | phba->hba_state = LPFC_HBA_ERROR; | 3272 | phba->link_state = LPFC_HBA_ERROR; |
3268 | /* | 3273 | /* |
3269 | * There was a link/board error. Read the | 3274 | * There was a link/board error. Read the |
3270 | * status register to retrieve the error event | 3275 | * status register to retrieve the error event |
@@ -3279,14 +3284,14 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3279 | /* Clear Chip error bit */ | 3284 | /* Clear Chip error bit */ |
3280 | writel(HA_ERATT, phba->HAregaddr); | 3285 | writel(HA_ERATT, phba->HAregaddr); |
3281 | readl(phba->HAregaddr); /* flush */ | 3286 | readl(phba->HAregaddr); /* flush */ |
3282 | phba->stopped = 1; | 3287 | phba->pport->stopped = 1; |
3283 | } | 3288 | } |
3284 | 3289 | ||
3285 | spin_lock(phba->host->host_lock); | 3290 | spin_lock(&phba->hbalock); |
3286 | phba->work_ha |= work_ha_copy; | 3291 | phba->work_ha |= work_ha_copy; |
3287 | if (phba->work_wait) | 3292 | if (phba->work_wait) |
3288 | wake_up(phba->work_wait); | 3293 | wake_up(phba->work_wait); |
3289 | spin_unlock(phba->host->host_lock); | 3294 | spin_unlock(&phba->hbalock); |
3290 | } | 3295 | } |
3291 | 3296 | ||
3292 | ha_copy &= ~(phba->work_ha_mask); | 3297 | ha_copy &= ~(phba->work_ha_mask); |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 41c38d324ab..0e857e51a2c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | /* forward declaration for LPFC_IOCB_t's use */ | 21 | /* forward declaration for LPFC_IOCB_t's use */ |
22 | struct lpfc_hba; | 22 | struct lpfc_hba; |
23 | struct lpfc_vport; | ||
23 | 24 | ||
24 | /* Define the context types that SLI handles for abort and sums. */ | 25 | /* Define the context types that SLI handles for abort and sums. */ |
25 | typedef enum _lpfc_ctx_cmd { | 26 | typedef enum _lpfc_ctx_cmd { |
@@ -47,6 +48,7 @@ struct lpfc_iocbq { | |||
47 | uint8_t abort_count; | 48 | uint8_t abort_count; |
48 | uint8_t rsvd2; | 49 | uint8_t rsvd2; |
49 | uint32_t drvrTimeout; /* driver timeout in seconds */ | 50 | uint32_t drvrTimeout; /* driver timeout in seconds */ |
51 | struct lpfc_vport *vport;/* virtual port pointer */ | ||
50 | void *context1; /* caller context information */ | 52 | void *context1; /* caller context information */ |
51 | void *context2; /* caller context information */ | 53 | void *context2; /* caller context information */ |
52 | void *context3; /* caller context information */ | 54 | void *context3; /* caller context information */ |
@@ -74,6 +76,7 @@ typedef struct lpfcMboxq { | |||
74 | /* MBOXQs are used in single linked lists */ | 76 | /* MBOXQs are used in single linked lists */ |
75 | struct list_head list; /* ptr to next mailbox command */ | 77 | struct list_head list; /* ptr to next mailbox command */ |
76 | MAILBOX_t mb; /* Mailbox cmd */ | 78 | MAILBOX_t mb; /* Mailbox cmd */ |
79 | struct lpfc_vport *vport;/* virutal port pointer */ | ||
77 | void *context1; /* caller context information */ | 80 | void *context1; /* caller context information */ |
78 | void *context2; /* caller context information */ | 81 | void *context2; /* caller context information */ |
79 | 82 | ||
@@ -197,6 +200,7 @@ struct lpfc_sli { | |||
197 | #define LPFC_SLI_MBOX_ACTIVE 0x100 /* HBA mailbox is currently active */ | 200 | #define LPFC_SLI_MBOX_ACTIVE 0x100 /* HBA mailbox is currently active */ |
198 | #define LPFC_SLI2_ACTIVE 0x200 /* SLI2 overlay in firmware is active */ | 201 | #define LPFC_SLI2_ACTIVE 0x200 /* SLI2 overlay in firmware is active */ |
199 | #define LPFC_PROCESS_LA 0x400 /* Able to process link attention */ | 202 | #define LPFC_PROCESS_LA 0x400 /* Able to process link attention */ |
203 | #define LPFC_BLOCK_MGMT_IO 0x800 /* Don't allow mgmt mbx or iocb cmds */ | ||
200 | 204 | ||
201 | struct lpfc_sli_ring ring[LPFC_MAX_RING]; | 205 | struct lpfc_sli_ring ring[LPFC_MAX_RING]; |
202 | int fcp_ring; /* ring used for FCP initiator commands */ | 206 | int fcp_ring; /* ring used for FCP initiator commands */ |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 92a9107019d..0a793735144 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -18,7 +18,7 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.1.12" | 21 | #define LPFC_DRIVER_VERSION "8.1.12_psplit" |
22 | 22 | ||
23 | #define LPFC_DRIVER_NAME "lpfc" | 23 | #define LPFC_DRIVER_NAME "lpfc" |
24 | 24 | ||