diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 20:19:08 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 20:19:08 -0500 |
commit | 9b73e76f3cf63379dcf45fcd4f112f5812418d0a (patch) | |
tree | 4e6bef87cd0cd6d848fc39a5ae25b981dbbe035b /drivers/scsi/lpfc | |
parent | 50d9a126240f9961cfdd063336bbeb91f77a7dce (diff) | |
parent | 23c3e290fb9ce38cabc2822b47583fc8702411bf (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (200 commits)
[SCSI] usbstorage: use last_sector_bug flag universally
[SCSI] libsas: abstract STP task status into a function
[SCSI] ultrastor: clean up inline asm warnings
[SCSI] aic7xxx: fix firmware build
[SCSI] aacraid: fib context lock for management ioctls
[SCSI] ch: remove forward declarations
[SCSI] ch: fix device minor number management bug
[SCSI] ch: handle class_device_create failure properly
[SCSI] NCR5380: fix section mismatch
[SCSI] sg: fix /proc/scsi/sg/devices when no SCSI devices
[SCSI] IB/iSER: add logical unit reset support
[SCSI] don't use __GFP_DMA for sense buffers if not required
[SCSI] use dynamically allocated sense buffer
[SCSI] scsi.h: add macro for enclosure bit of inquiry data
[SCSI] sd: add fix for devices with last sector access problems
[SCSI] fix pcmcia compile problem
[SCSI] aacraid: add Voodoo Lite class of cards.
[SCSI] aacraid: add new driver features flags
[SCSI] qla2xxx: Update version number to 8.02.00-k7.
[SCSI] qla2xxx: Issue correct MBC_INITIALIZE_FIRMWARE command.
...
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 53 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 217 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 33 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 304 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_debugfs.c | 157 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_disc.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 623 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 372 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 112 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 429 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_logmsg.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 32 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mem.c | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 160 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 54 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 534 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.h | 12 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_version.h | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 93 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.h | 2 |
21 files changed, 2318 insertions, 880 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index ba3ecab9baf3..f26b9538affe 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -29,7 +29,8 @@ struct lpfc_sli2_slim; | |||
29 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact | 29 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact |
30 | the NameServer before giving up. */ | 30 | the NameServer before giving up. */ |
31 | #define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ | 31 | #define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ |
32 | #define LPFC_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ | 32 | #define LPFC_DEFAULT_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ |
33 | #define LPFC_MAX_SG_SEG_CNT 256 /* sg element count per scsi cmnd */ | ||
33 | #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ | 34 | #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ |
34 | #define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ | 35 | #define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ |
35 | 36 | ||
@@ -68,6 +69,7 @@ struct lpfc_dmabuf { | |||
68 | struct list_head list; | 69 | struct list_head list; |
69 | void *virt; /* virtual address ptr */ | 70 | void *virt; /* virtual address ptr */ |
70 | dma_addr_t phys; /* mapped address */ | 71 | dma_addr_t phys; /* mapped address */ |
72 | uint32_t buffer_tag; /* used for tagged queue ring */ | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | struct lpfc_dma_pool { | 75 | struct lpfc_dma_pool { |
@@ -272,10 +274,16 @@ struct lpfc_vport { | |||
272 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ | 274 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ |
273 | #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ | 275 | #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ |
274 | #define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ | 276 | #define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ |
275 | #define FC_RFF_NOT_SUPPORTED 0x40000 /* RFF_ID was rejected by switch */ | ||
276 | #define FC_VPORT_NEEDS_REG_VPI 0x80000 /* Needs to have its vpi registered */ | 277 | #define FC_VPORT_NEEDS_REG_VPI 0x80000 /* Needs to have its vpi registered */ |
277 | #define FC_RSCN_DEFERRED 0x100000 /* A deferred RSCN being processed */ | 278 | #define FC_RSCN_DEFERRED 0x100000 /* A deferred RSCN being processed */ |
278 | 279 | ||
280 | uint32_t ct_flags; | ||
281 | #define FC_CT_RFF_ID 0x1 /* RFF_ID accepted by switch */ | ||
282 | #define FC_CT_RNN_ID 0x2 /* RNN_ID accepted by switch */ | ||
283 | #define FC_CT_RSNN_NN 0x4 /* RSNN_NN accepted by switch */ | ||
284 | #define FC_CT_RSPN_ID 0x8 /* RSPN_ID accepted by switch */ | ||
285 | #define FC_CT_RFT_ID 0x10 /* RFT_ID accepted by switch */ | ||
286 | |||
279 | struct list_head fc_nodes; | 287 | struct list_head fc_nodes; |
280 | 288 | ||
281 | /* Keep counters for the number of entries in each list. */ | 289 | /* Keep counters for the number of entries in each list. */ |
@@ -344,6 +352,7 @@ struct lpfc_vport { | |||
344 | uint32_t cfg_discovery_threads; | 352 | uint32_t cfg_discovery_threads; |
345 | uint32_t cfg_log_verbose; | 353 | uint32_t cfg_log_verbose; |
346 | uint32_t cfg_max_luns; | 354 | uint32_t cfg_max_luns; |
355 | uint32_t cfg_enable_da_id; | ||
347 | 356 | ||
348 | uint32_t dev_loss_tmo_changed; | 357 | uint32_t dev_loss_tmo_changed; |
349 | 358 | ||
@@ -360,6 +369,7 @@ struct lpfc_vport { | |||
360 | 369 | ||
361 | struct hbq_s { | 370 | struct hbq_s { |
362 | uint16_t entry_count; /* Current number of HBQ slots */ | 371 | uint16_t entry_count; /* Current number of HBQ slots */ |
372 | uint16_t buffer_count; /* Current number of buffers posted */ | ||
363 | uint32_t next_hbqPutIdx; /* Index to next HBQ slot to use */ | 373 | uint32_t next_hbqPutIdx; /* Index to next HBQ slot to use */ |
364 | uint32_t hbqPutIdx; /* HBQ slot to use */ | 374 | uint32_t hbqPutIdx; /* HBQ slot to use */ |
365 | uint32_t local_hbqGetIdx; /* Local copy of Get index from Port */ | 375 | uint32_t local_hbqGetIdx; /* Local copy of Get index from Port */ |
@@ -377,6 +387,11 @@ struct hbq_s { | |||
377 | #define LPFC_ELS_HBQ 0 | 387 | #define LPFC_ELS_HBQ 0 |
378 | #define LPFC_EXTRA_HBQ 1 | 388 | #define LPFC_EXTRA_HBQ 1 |
379 | 389 | ||
390 | enum hba_temp_state { | ||
391 | HBA_NORMAL_TEMP, | ||
392 | HBA_OVER_TEMP | ||
393 | }; | ||
394 | |||
380 | struct lpfc_hba { | 395 | struct lpfc_hba { |
381 | struct lpfc_sli sli; | 396 | struct lpfc_sli sli; |
382 | uint32_t sli_rev; /* SLI2 or SLI3 */ | 397 | uint32_t sli_rev; /* SLI2 or SLI3 */ |
@@ -457,7 +472,8 @@ struct lpfc_hba { | |||
457 | uint64_t cfg_soft_wwnn; | 472 | uint64_t cfg_soft_wwnn; |
458 | uint64_t cfg_soft_wwpn; | 473 | uint64_t cfg_soft_wwpn; |
459 | uint32_t cfg_hba_queue_depth; | 474 | uint32_t cfg_hba_queue_depth; |
460 | 475 | uint32_t cfg_enable_hba_reset; | |
476 | uint32_t cfg_enable_hba_heartbeat; | ||
461 | 477 | ||
462 | lpfc_vpd_t vpd; /* vital product data */ | 478 | lpfc_vpd_t vpd; /* vital product data */ |
463 | 479 | ||
@@ -544,8 +560,7 @@ struct lpfc_hba { | |||
544 | struct list_head port_list; | 560 | struct list_head port_list; |
545 | struct lpfc_vport *pport; /* physical lpfc_vport pointer */ | 561 | struct lpfc_vport *pport; /* physical lpfc_vport pointer */ |
546 | uint16_t max_vpi; /* Maximum virtual nports */ | 562 | uint16_t max_vpi; /* Maximum virtual nports */ |
547 | #define LPFC_MAX_VPI 100 /* Max number of VPI supported */ | 563 | #define LPFC_MAX_VPI 0xFFFF /* Max number of VPI supported */ |
548 | #define LPFC_MAX_VPORTS (LPFC_MAX_VPI+1)/* Max number of VPorts supported */ | ||
549 | unsigned long *vpi_bmask; /* vpi allocation table */ | 564 | unsigned long *vpi_bmask; /* vpi allocation table */ |
550 | 565 | ||
551 | /* Data structure used by fabric iocb scheduler */ | 566 | /* Data structure used by fabric iocb scheduler */ |
@@ -563,16 +578,30 @@ struct lpfc_hba { | |||
563 | struct dentry *hba_debugfs_root; | 578 | struct dentry *hba_debugfs_root; |
564 | atomic_t debugfs_vport_count; | 579 | atomic_t debugfs_vport_count; |
565 | struct dentry *debug_hbqinfo; | 580 | struct dentry *debug_hbqinfo; |
566 | struct dentry *debug_dumpslim; | 581 | struct dentry *debug_dumpHostSlim; |
582 | struct dentry *debug_dumpHBASlim; | ||
567 | struct dentry *debug_slow_ring_trc; | 583 | struct dentry *debug_slow_ring_trc; |
568 | struct lpfc_debugfs_trc *slow_ring_trc; | 584 | struct lpfc_debugfs_trc *slow_ring_trc; |
569 | atomic_t slow_ring_trc_cnt; | 585 | atomic_t slow_ring_trc_cnt; |
570 | #endif | 586 | #endif |
571 | 587 | ||
588 | /* Used for deferred freeing of ELS data buffers */ | ||
589 | struct list_head elsbuf; | ||
590 | int elsbuf_cnt; | ||
591 | int elsbuf_prev_cnt; | ||
592 | |||
593 | uint8_t temp_sensor_support; | ||
572 | /* Fields used for heart beat. */ | 594 | /* Fields used for heart beat. */ |
573 | unsigned long last_completion_time; | 595 | unsigned long last_completion_time; |
574 | struct timer_list hb_tmofunc; | 596 | struct timer_list hb_tmofunc; |
575 | uint8_t hb_outstanding; | 597 | uint8_t hb_outstanding; |
598 | /* | ||
599 | * Following bit will be set for all buffer tags which are not | ||
600 | * associated with any HBQ. | ||
601 | */ | ||
602 | #define QUE_BUFTAG_BIT (1<<31) | ||
603 | uint32_t buffer_tag_count; | ||
604 | enum hba_temp_state over_temp_state; | ||
576 | }; | 605 | }; |
577 | 606 | ||
578 | static inline struct Scsi_Host * | 607 | static inline struct Scsi_Host * |
@@ -598,5 +627,15 @@ lpfc_is_link_up(struct lpfc_hba *phba) | |||
598 | phba->link_state == LPFC_HBA_READY; | 627 | phba->link_state == LPFC_HBA_READY; |
599 | } | 628 | } |
600 | 629 | ||
601 | #define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */ | 630 | #define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */ |
631 | #define FC_REG_TEMPERATURE_EVENT 0x20 /* Register for temperature | ||
632 | event */ | ||
602 | 633 | ||
634 | struct temp_event { | ||
635 | uint32_t event_type; | ||
636 | uint32_t event_code; | ||
637 | uint32_t data; | ||
638 | }; | ||
639 | #define LPFC_CRIT_TEMP 0x1 | ||
640 | #define LPFC_THRESHOLD_TEMP 0x2 | ||
641 | #define LPFC_NORMAL_TEMP 0x3 | ||
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 80a11218b9bb..4bae4a2ed2f1 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.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-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 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 * |
@@ -45,6 +45,10 @@ | |||
45 | #define LPFC_MIN_DEVLOSS_TMO 1 | 45 | #define LPFC_MIN_DEVLOSS_TMO 1 |
46 | #define LPFC_MAX_DEVLOSS_TMO 255 | 46 | #define LPFC_MAX_DEVLOSS_TMO 255 |
47 | 47 | ||
48 | #define LPFC_MAX_LINK_SPEED 8 | ||
49 | #define LPFC_LINK_SPEED_BITMAP 0x00000117 | ||
50 | #define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8" | ||
51 | |||
48 | static void | 52 | static void |
49 | lpfc_jedec_to_ascii(int incr, char hdw[]) | 53 | lpfc_jedec_to_ascii(int incr, char hdw[]) |
50 | { | 54 | { |
@@ -86,6 +90,15 @@ lpfc_serialnum_show(struct class_device *cdev, char *buf) | |||
86 | } | 90 | } |
87 | 91 | ||
88 | static ssize_t | 92 | static ssize_t |
93 | lpfc_temp_sensor_show(struct class_device *cdev, char *buf) | ||
94 | { | ||
95 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
96 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
97 | struct lpfc_hba *phba = vport->phba; | ||
98 | return snprintf(buf, PAGE_SIZE, "%d\n",phba->temp_sensor_support); | ||
99 | } | ||
100 | |||
101 | static ssize_t | ||
89 | lpfc_modeldesc_show(struct class_device *cdev, char *buf) | 102 | lpfc_modeldesc_show(struct class_device *cdev, char *buf) |
90 | { | 103 | { |
91 | struct Scsi_Host *shost = class_to_shost(cdev); | 104 | struct Scsi_Host *shost = class_to_shost(cdev); |
@@ -178,12 +191,9 @@ lpfc_state_show(struct class_device *cdev, char *buf) | |||
178 | case LPFC_LINK_UP: | 191 | case LPFC_LINK_UP: |
179 | case LPFC_CLEAR_LA: | 192 | case LPFC_CLEAR_LA: |
180 | case LPFC_HBA_READY: | 193 | case LPFC_HBA_READY: |
181 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Up - \n"); | 194 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Up - "); |
182 | 195 | ||
183 | switch (vport->port_state) { | 196 | switch (vport->port_state) { |
184 | len += snprintf(buf + len, PAGE_SIZE-len, | ||
185 | "initializing\n"); | ||
186 | break; | ||
187 | case LPFC_LOCAL_CFG_LINK: | 197 | case LPFC_LOCAL_CFG_LINK: |
188 | len += snprintf(buf + len, PAGE_SIZE-len, | 198 | len += snprintf(buf + len, PAGE_SIZE-len, |
189 | "Configuring Link\n"); | 199 | "Configuring Link\n"); |
@@ -252,8 +262,7 @@ lpfc_issue_lip(struct Scsi_Host *shost) | |||
252 | int mbxstatus = MBXERR_ERROR; | 262 | int mbxstatus = MBXERR_ERROR; |
253 | 263 | ||
254 | if ((vport->fc_flag & FC_OFFLINE_MODE) || | 264 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
255 | (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) || | 265 | (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)) |
256 | (vport->port_state != LPFC_VPORT_READY)) | ||
257 | return -EPERM; | 266 | return -EPERM; |
258 | 267 | ||
259 | pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); | 268 | pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); |
@@ -305,12 +314,14 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) | |||
305 | 314 | ||
306 | psli = &phba->sli; | 315 | psli = &phba->sli; |
307 | 316 | ||
317 | /* Wait a little for things to settle down, but not | ||
318 | * long enough for dev loss timeout to expire. | ||
319 | */ | ||
308 | for (i = 0; i < psli->num_rings; i++) { | 320 | for (i = 0; i < psli->num_rings; i++) { |
309 | pring = &psli->ring[i]; | 321 | pring = &psli->ring[i]; |
310 | /* The linkdown event takes 30 seconds to timeout. */ | ||
311 | while (pring->txcmplq_cnt) { | 322 | while (pring->txcmplq_cnt) { |
312 | msleep(10); | 323 | msleep(10); |
313 | if (cnt++ > 3000) { | 324 | if (cnt++ > 500) { /* 5 secs */ |
314 | lpfc_printf_log(phba, | 325 | lpfc_printf_log(phba, |
315 | KERN_WARNING, LOG_INIT, | 326 | KERN_WARNING, LOG_INIT, |
316 | "0466 Outstanding IO when " | 327 | "0466 Outstanding IO when " |
@@ -336,6 +347,9 @@ lpfc_selective_reset(struct lpfc_hba *phba) | |||
336 | struct completion online_compl; | 347 | struct completion online_compl; |
337 | int status = 0; | 348 | int status = 0; |
338 | 349 | ||
350 | if (!phba->cfg_enable_hba_reset) | ||
351 | return -EIO; | ||
352 | |||
339 | status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); | 353 | status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); |
340 | 354 | ||
341 | if (status != 0) | 355 | if (status != 0) |
@@ -409,6 +423,8 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) | |||
409 | struct completion online_compl; | 423 | struct completion online_compl; |
410 | int status=0; | 424 | int status=0; |
411 | 425 | ||
426 | if (!phba->cfg_enable_hba_reset) | ||
427 | return -EACCES; | ||
412 | init_completion(&online_compl); | 428 | init_completion(&online_compl); |
413 | 429 | ||
414 | if(strncmp(buf, "online", sizeof("online") - 1) == 0) { | 430 | if(strncmp(buf, "online", sizeof("online") - 1) == 0) { |
@@ -908,6 +924,8 @@ static CLASS_DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL); | |||
908 | static CLASS_DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL); | 924 | static CLASS_DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL); |
909 | static CLASS_DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL); | 925 | static CLASS_DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL); |
910 | static CLASS_DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL); | 926 | static CLASS_DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL); |
927 | static CLASS_DEVICE_ATTR(lpfc_temp_sensor, S_IRUGO, lpfc_temp_sensor_show, | ||
928 | NULL); | ||
911 | 929 | ||
912 | 930 | ||
913 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; | 931 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; |
@@ -971,6 +989,14 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) | |||
971 | unsigned int i, j, cnt=count; | 989 | unsigned int i, j, cnt=count; |
972 | u8 wwpn[8]; | 990 | u8 wwpn[8]; |
973 | 991 | ||
992 | if (!phba->cfg_enable_hba_reset) | ||
993 | return -EACCES; | ||
994 | spin_lock_irq(&phba->hbalock); | ||
995 | if (phba->over_temp_state == HBA_OVER_TEMP) { | ||
996 | spin_unlock_irq(&phba->hbalock); | ||
997 | return -EACCES; | ||
998 | } | ||
999 | spin_unlock_irq(&phba->hbalock); | ||
974 | /* count may include a LF at end of string */ | 1000 | /* count may include a LF at end of string */ |
975 | if (buf[cnt-1] == '\n') | 1001 | if (buf[cnt-1] == '\n') |
976 | cnt--; | 1002 | cnt--; |
@@ -1102,7 +1128,13 @@ MODULE_PARM_DESC(lpfc_sli_mode, "SLI mode selector:" | |||
1102 | " 2 - select SLI-2 even on SLI-3 capable HBAs," | 1128 | " 2 - select SLI-2 even on SLI-3 capable HBAs," |
1103 | " 3 - select SLI-3"); | 1129 | " 3 - select SLI-3"); |
1104 | 1130 | ||
1105 | LPFC_ATTR_R(enable_npiv, 0, 0, 1, "Enable NPIV functionality"); | 1131 | int lpfc_enable_npiv = 0; |
1132 | module_param(lpfc_enable_npiv, int, 0); | ||
1133 | MODULE_PARM_DESC(lpfc_enable_npiv, "Enable NPIV functionality"); | ||
1134 | lpfc_param_show(enable_npiv); | ||
1135 | lpfc_param_init(enable_npiv, 0, 0, 1); | ||
1136 | static CLASS_DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, | ||
1137 | lpfc_enable_npiv_show, NULL); | ||
1106 | 1138 | ||
1107 | /* | 1139 | /* |
1108 | # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear | 1140 | # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear |
@@ -1248,6 +1280,13 @@ LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, | |||
1248 | "Verbose logging bit-mask"); | 1280 | "Verbose logging bit-mask"); |
1249 | 1281 | ||
1250 | /* | 1282 | /* |
1283 | # lpfc_enable_da_id: This turns on the DA_ID CT command that deregisters | ||
1284 | # objects that have been registered with the nameserver after login. | ||
1285 | */ | ||
1286 | LPFC_VPORT_ATTR_R(enable_da_id, 0, 0, 1, | ||
1287 | "Deregister nameserver objects before LOGO"); | ||
1288 | |||
1289 | /* | ||
1251 | # lun_queue_depth: This parameter is used to limit the number of outstanding | 1290 | # lun_queue_depth: This parameter is used to limit the number of outstanding |
1252 | # commands per FCP LUN. Value range is [1,128]. Default value is 30. | 1291 | # commands per FCP LUN. Value range is [1,128]. Default value is 30. |
1253 | */ | 1292 | */ |
@@ -1369,7 +1408,33 @@ LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1, | |||
1369 | # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6]. | 1408 | # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6]. |
1370 | # Default value is 0. | 1409 | # Default value is 0. |
1371 | */ | 1410 | */ |
1372 | LPFC_ATTR_RW(topology, 0, 0, 6, "Select Fibre Channel topology"); | 1411 | static int |
1412 | lpfc_topology_set(struct lpfc_hba *phba, int val) | ||
1413 | { | ||
1414 | int err; | ||
1415 | uint32_t prev_val; | ||
1416 | if (val >= 0 && val <= 6) { | ||
1417 | prev_val = phba->cfg_topology; | ||
1418 | phba->cfg_topology = val; | ||
1419 | err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport)); | ||
1420 | if (err) | ||
1421 | phba->cfg_topology = prev_val; | ||
1422 | return err; | ||
1423 | } | ||
1424 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1425 | "%d:0467 lpfc_topology attribute cannot be set to %d, " | ||
1426 | "allowed range is [0, 6]\n", | ||
1427 | phba->brd_no, val); | ||
1428 | return -EINVAL; | ||
1429 | } | ||
1430 | static int lpfc_topology = 0; | ||
1431 | module_param(lpfc_topology, int, 0); | ||
1432 | MODULE_PARM_DESC(lpfc_topology, "Select Fibre Channel topology"); | ||
1433 | lpfc_param_show(topology) | ||
1434 | lpfc_param_init(topology, 0, 0, 6) | ||
1435 | lpfc_param_store(topology) | ||
1436 | static CLASS_DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR, | ||
1437 | lpfc_topology_show, lpfc_topology_store); | ||
1373 | 1438 | ||
1374 | /* | 1439 | /* |
1375 | # lpfc_link_speed: Link speed selection for initializing the Fibre Channel | 1440 | # lpfc_link_speed: Link speed selection for initializing the Fibre Channel |
@@ -1381,7 +1446,59 @@ LPFC_ATTR_RW(topology, 0, 0, 6, "Select Fibre Channel topology"); | |||
1381 | # 8 = 8 Gigabaud | 1446 | # 8 = 8 Gigabaud |
1382 | # Value range is [0,8]. Default value is 0. | 1447 | # Value range is [0,8]. Default value is 0. |
1383 | */ | 1448 | */ |
1384 | LPFC_ATTR_R(link_speed, 0, 0, 8, "Select link speed"); | 1449 | static int |
1450 | lpfc_link_speed_set(struct lpfc_hba *phba, int val) | ||
1451 | { | ||
1452 | int err; | ||
1453 | uint32_t prev_val; | ||
1454 | |||
1455 | if (((val == LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) || | ||
1456 | ((val == LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) || | ||
1457 | ((val == LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) || | ||
1458 | ((val == LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) || | ||
1459 | ((val == LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb))) | ||
1460 | return -EINVAL; | ||
1461 | |||
1462 | if ((val >= 0 && val <= LPFC_MAX_LINK_SPEED) | ||
1463 | && (LPFC_LINK_SPEED_BITMAP & (1 << val))) { | ||
1464 | prev_val = phba->cfg_link_speed; | ||
1465 | phba->cfg_link_speed = val; | ||
1466 | err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport)); | ||
1467 | if (err) | ||
1468 | phba->cfg_link_speed = prev_val; | ||
1469 | return err; | ||
1470 | } | ||
1471 | |||
1472 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1473 | "%d:0469 lpfc_link_speed attribute cannot be set to %d, " | ||
1474 | "allowed range is [0, 8]\n", | ||
1475 | phba->brd_no, val); | ||
1476 | return -EINVAL; | ||
1477 | } | ||
1478 | |||
1479 | static int lpfc_link_speed = 0; | ||
1480 | module_param(lpfc_link_speed, int, 0); | ||
1481 | MODULE_PARM_DESC(lpfc_link_speed, "Select link speed"); | ||
1482 | lpfc_param_show(link_speed) | ||
1483 | static int | ||
1484 | lpfc_link_speed_init(struct lpfc_hba *phba, int val) | ||
1485 | { | ||
1486 | if ((val >= 0 && val <= LPFC_MAX_LINK_SPEED) | ||
1487 | && (LPFC_LINK_SPEED_BITMAP & (1 << val))) { | ||
1488 | phba->cfg_link_speed = val; | ||
1489 | return 0; | ||
1490 | } | ||
1491 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1492 | "0454 lpfc_link_speed attribute cannot " | ||
1493 | "be set to %d, allowed values are " | ||
1494 | "["LPFC_LINK_SPEED_STRING"]\n", val); | ||
1495 | phba->cfg_link_speed = 0; | ||
1496 | return -EINVAL; | ||
1497 | } | ||
1498 | |||
1499 | lpfc_param_store(link_speed) | ||
1500 | static CLASS_DEVICE_ATTR(lpfc_link_speed, S_IRUGO | S_IWUSR, | ||
1501 | lpfc_link_speed_show, lpfc_link_speed_store); | ||
1385 | 1502 | ||
1386 | /* | 1503 | /* |
1387 | # lpfc_fcp_class: Determines FC class to use for the FCP protocol. | 1504 | # lpfc_fcp_class: Determines FC class to use for the FCP protocol. |
@@ -1479,7 +1596,30 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255, | |||
1479 | */ | 1596 | */ |
1480 | LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); | 1597 | LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); |
1481 | 1598 | ||
1599 | /* | ||
1600 | # lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware. | ||
1601 | # 0 = HBA resets disabled | ||
1602 | # 1 = HBA resets enabled (default) | ||
1603 | # Value range is [0,1]. Default value is 1. | ||
1604 | */ | ||
1605 | LPFC_ATTR_R(enable_hba_reset, 1, 0, 1, "Enable HBA resets from the driver."); | ||
1606 | |||
1607 | /* | ||
1608 | # lpfc_enable_hba_heartbeat: Enable HBA heartbeat timer.. | ||
1609 | # 0 = HBA Heartbeat disabled | ||
1610 | # 1 = HBA Heartbeat enabled (default) | ||
1611 | # Value range is [0,1]. Default value is 1. | ||
1612 | */ | ||
1613 | LPFC_ATTR_R(enable_hba_heartbeat, 1, 0, 1, "Enable HBA Heartbeat."); | ||
1482 | 1614 | ||
1615 | /* | ||
1616 | * lpfc_sg_seg_cnt: Initial Maximum DMA Segment Count | ||
1617 | * This value can be set to values between 64 and 256. The default value is | ||
1618 | * 64, but may be increased to allow for larger Max I/O sizes. The scsi layer | ||
1619 | * will be allowed to request I/Os of sizes up to (MAX_SEG_COUNT * SEG_SIZE). | ||
1620 | */ | ||
1621 | LPFC_ATTR_R(sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, LPFC_DEFAULT_SG_SEG_CNT, | ||
1622 | LPFC_MAX_SG_SEG_CNT, "Max Scatter Gather Segment Count"); | ||
1483 | 1623 | ||
1484 | struct class_device_attribute *lpfc_hba_attrs[] = { | 1624 | struct class_device_attribute *lpfc_hba_attrs[] = { |
1485 | &class_device_attr_info, | 1625 | &class_device_attr_info, |
@@ -1494,6 +1634,7 @@ struct class_device_attribute *lpfc_hba_attrs[] = { | |||
1494 | &class_device_attr_state, | 1634 | &class_device_attr_state, |
1495 | &class_device_attr_num_discovered_ports, | 1635 | &class_device_attr_num_discovered_ports, |
1496 | &class_device_attr_lpfc_drvr_version, | 1636 | &class_device_attr_lpfc_drvr_version, |
1637 | &class_device_attr_lpfc_temp_sensor, | ||
1497 | &class_device_attr_lpfc_log_verbose, | 1638 | &class_device_attr_lpfc_log_verbose, |
1498 | &class_device_attr_lpfc_lun_queue_depth, | 1639 | &class_device_attr_lpfc_lun_queue_depth, |
1499 | &class_device_attr_lpfc_hba_queue_depth, | 1640 | &class_device_attr_lpfc_hba_queue_depth, |
@@ -1530,6 +1671,9 @@ struct class_device_attribute *lpfc_hba_attrs[] = { | |||
1530 | &class_device_attr_lpfc_soft_wwnn, | 1671 | &class_device_attr_lpfc_soft_wwnn, |
1531 | &class_device_attr_lpfc_soft_wwpn, | 1672 | &class_device_attr_lpfc_soft_wwpn, |
1532 | &class_device_attr_lpfc_soft_wwn_enable, | 1673 | &class_device_attr_lpfc_soft_wwn_enable, |
1674 | &class_device_attr_lpfc_enable_hba_reset, | ||
1675 | &class_device_attr_lpfc_enable_hba_heartbeat, | ||
1676 | &class_device_attr_lpfc_sg_seg_cnt, | ||
1533 | NULL, | 1677 | NULL, |
1534 | }; | 1678 | }; |
1535 | 1679 | ||
@@ -1552,6 +1696,7 @@ struct class_device_attribute *lpfc_vport_attrs[] = { | |||
1552 | &class_device_attr_lpfc_max_luns, | 1696 | &class_device_attr_lpfc_max_luns, |
1553 | &class_device_attr_nport_evt_cnt, | 1697 | &class_device_attr_nport_evt_cnt, |
1554 | &class_device_attr_npiv_info, | 1698 | &class_device_attr_npiv_info, |
1699 | &class_device_attr_lpfc_enable_da_id, | ||
1555 | NULL, | 1700 | NULL, |
1556 | }; | 1701 | }; |
1557 | 1702 | ||
@@ -1727,13 +1872,18 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1727 | 1872 | ||
1728 | spin_lock_irq(&phba->hbalock); | 1873 | spin_lock_irq(&phba->hbalock); |
1729 | 1874 | ||
1875 | if (phba->over_temp_state == HBA_OVER_TEMP) { | ||
1876 | sysfs_mbox_idle(phba); | ||
1877 | spin_unlock_irq(&phba->hbalock); | ||
1878 | return -EACCES; | ||
1879 | } | ||
1880 | |||
1730 | if (off == 0 && | 1881 | if (off == 0 && |
1731 | phba->sysfs_mbox.state == SMBOX_WRITING && | 1882 | phba->sysfs_mbox.state == SMBOX_WRITING && |
1732 | phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) { | 1883 | phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) { |
1733 | 1884 | ||
1734 | switch (phba->sysfs_mbox.mbox->mb.mbxCommand) { | 1885 | switch (phba->sysfs_mbox.mbox->mb.mbxCommand) { |
1735 | /* Offline only */ | 1886 | /* Offline only */ |
1736 | case MBX_WRITE_NV: | ||
1737 | case MBX_INIT_LINK: | 1887 | case MBX_INIT_LINK: |
1738 | case MBX_DOWN_LINK: | 1888 | case MBX_DOWN_LINK: |
1739 | case MBX_CONFIG_LINK: | 1889 | case MBX_CONFIG_LINK: |
@@ -1744,9 +1894,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1744 | case MBX_DUMP_CONTEXT: | 1894 | case MBX_DUMP_CONTEXT: |
1745 | case MBX_RUN_DIAGS: | 1895 | case MBX_RUN_DIAGS: |
1746 | case MBX_RESTART: | 1896 | case MBX_RESTART: |
1747 | case MBX_FLASH_WR_ULA: | ||
1748 | case MBX_SET_MASK: | 1897 | case MBX_SET_MASK: |
1749 | case MBX_SET_SLIM: | ||
1750 | case MBX_SET_DEBUG: | 1898 | case MBX_SET_DEBUG: |
1751 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) { | 1899 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) { |
1752 | printk(KERN_WARNING "mbox_read:Command 0x%x " | 1900 | printk(KERN_WARNING "mbox_read:Command 0x%x " |
@@ -1756,6 +1904,8 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1756 | spin_unlock_irq(&phba->hbalock); | 1904 | spin_unlock_irq(&phba->hbalock); |
1757 | return -EPERM; | 1905 | return -EPERM; |
1758 | } | 1906 | } |
1907 | case MBX_WRITE_NV: | ||
1908 | case MBX_WRITE_VPARMS: | ||
1759 | case MBX_LOAD_SM: | 1909 | case MBX_LOAD_SM: |
1760 | case MBX_READ_NV: | 1910 | case MBX_READ_NV: |
1761 | case MBX_READ_CONFIG: | 1911 | case MBX_READ_CONFIG: |
@@ -1772,6 +1922,8 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1772 | case MBX_LOAD_EXP_ROM: | 1922 | case MBX_LOAD_EXP_ROM: |
1773 | case MBX_BEACON: | 1923 | case MBX_BEACON: |
1774 | case MBX_DEL_LD_ENTRY: | 1924 | case MBX_DEL_LD_ENTRY: |
1925 | case MBX_SET_VARIABLE: | ||
1926 | case MBX_WRITE_WWN: | ||
1775 | break; | 1927 | break; |
1776 | case MBX_READ_SPARM64: | 1928 | case MBX_READ_SPARM64: |
1777 | case MBX_READ_LA: | 1929 | case MBX_READ_LA: |
@@ -1793,6 +1945,17 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1793 | return -EPERM; | 1945 | return -EPERM; |
1794 | } | 1946 | } |
1795 | 1947 | ||
1948 | /* If HBA encountered an error attention, allow only DUMP | ||
1949 | * mailbox command until the HBA is restarted. | ||
1950 | */ | ||
1951 | if ((phba->pport->stopped) && | ||
1952 | (phba->sysfs_mbox.mbox->mb.mbxCommand | ||
1953 | != MBX_DUMP_MEMORY)) { | ||
1954 | sysfs_mbox_idle(phba); | ||
1955 | spin_unlock_irq(&phba->hbalock); | ||
1956 | return -EPERM; | ||
1957 | } | ||
1958 | |||
1796 | phba->sysfs_mbox.mbox->vport = vport; | 1959 | phba->sysfs_mbox.mbox->vport = vport; |
1797 | 1960 | ||
1798 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { | 1961 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { |
@@ -1993,7 +2156,8 @@ lpfc_get_host_speed(struct Scsi_Host *shost) | |||
1993 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; | 2156 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; |
1994 | break; | 2157 | break; |
1995 | } | 2158 | } |
1996 | } | 2159 | } else |
2160 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; | ||
1997 | 2161 | ||
1998 | spin_unlock_irq(shost->host_lock); | 2162 | spin_unlock_irq(shost->host_lock); |
1999 | } | 2163 | } |
@@ -2013,7 +2177,7 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost) | |||
2013 | node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn); | 2177 | node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn); |
2014 | else | 2178 | else |
2015 | /* fabric is local port if there is no F/FL_Port */ | 2179 | /* fabric is local port if there is no F/FL_Port */ |
2016 | node_name = wwn_to_u64(vport->fc_nodename.u.wwn); | 2180 | node_name = 0; |
2017 | 2181 | ||
2018 | spin_unlock_irq(shost->host_lock); | 2182 | spin_unlock_irq(shost->host_lock); |
2019 | 2183 | ||
@@ -2337,8 +2501,6 @@ struct fc_function_template lpfc_transport_functions = { | |||
2337 | .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk, | 2501 | .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk, |
2338 | .terminate_rport_io = lpfc_terminate_rport_io, | 2502 | .terminate_rport_io = lpfc_terminate_rport_io, |
2339 | 2503 | ||
2340 | .vport_create = lpfc_vport_create, | ||
2341 | .vport_delete = lpfc_vport_delete, | ||
2342 | .dd_fcvport_size = sizeof(struct lpfc_vport *), | 2504 | .dd_fcvport_size = sizeof(struct lpfc_vport *), |
2343 | }; | 2505 | }; |
2344 | 2506 | ||
@@ -2414,21 +2576,23 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
2414 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); | 2576 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); |
2415 | lpfc_enable_npiv_init(phba, lpfc_enable_npiv); | 2577 | lpfc_enable_npiv_init(phba, lpfc_enable_npiv); |
2416 | lpfc_use_msi_init(phba, lpfc_use_msi); | 2578 | lpfc_use_msi_init(phba, lpfc_use_msi); |
2579 | lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset); | ||
2580 | lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat); | ||
2417 | phba->cfg_poll = lpfc_poll; | 2581 | phba->cfg_poll = lpfc_poll; |
2418 | phba->cfg_soft_wwnn = 0L; | 2582 | phba->cfg_soft_wwnn = 0L; |
2419 | phba->cfg_soft_wwpn = 0L; | 2583 | phba->cfg_soft_wwpn = 0L; |
2420 | /* | 2584 | lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt); |
2421 | * The total number of segments is the configuration value plus 2 | 2585 | /* Also reinitialize the host templates with new values. */ |
2422 | * since the IOCB need a command and response bde. | 2586 | lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; |
2423 | */ | 2587 | lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; |
2424 | phba->cfg_sg_seg_cnt = LPFC_SG_SEG_CNT + 2; | ||
2425 | /* | 2588 | /* |
2426 | * Since the sg_tablesize is module parameter, the sg_dma_buf_size | 2589 | * Since the sg_tablesize is module parameter, the sg_dma_buf_size |
2427 | * used to create the sg_dma_buf_pool must be dynamically calculated | 2590 | * used to create the sg_dma_buf_pool must be dynamically calculated. |
2591 | * 2 segments are added since the IOCB needs a command and response bde. | ||
2428 | */ | 2592 | */ |
2429 | phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + | 2593 | phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + |
2430 | sizeof(struct fcp_rsp) + | 2594 | sizeof(struct fcp_rsp) + |
2431 | (phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64)); | 2595 | ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct ulp_bde64)); |
2432 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); | 2596 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); |
2433 | return; | 2597 | return; |
2434 | } | 2598 | } |
@@ -2448,5 +2612,6 @@ lpfc_get_vport_cfgparam(struct lpfc_vport *vport) | |||
2448 | lpfc_discovery_threads_init(vport, lpfc_discovery_threads); | 2612 | lpfc_discovery_threads_init(vport, lpfc_discovery_threads); |
2449 | lpfc_max_luns_init(vport, lpfc_max_luns); | 2613 | lpfc_max_luns_init(vport, lpfc_max_luns); |
2450 | lpfc_scan_down_init(vport, lpfc_scan_down); | 2614 | lpfc_scan_down_init(vport, lpfc_scan_down); |
2615 | lpfc_enable_da_id_init(vport, lpfc_enable_da_id); | ||
2451 | return; | 2616 | return; |
2452 | } | 2617 | } |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index a599e1510710..50fcb7c930bc 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -23,6 +23,8 @@ typedef int (*node_filter)(struct lpfc_nodelist *ndlp, void *param); | |||
23 | struct fc_rport; | 23 | struct fc_rport; |
24 | void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); | 24 | void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); |
25 | void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); | 25 | void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); |
26 | void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); | ||
27 | |||
26 | void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *); | 28 | void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *); |
27 | int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, | 29 | int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, |
28 | struct lpfc_dmabuf *mp); | 30 | struct lpfc_dmabuf *mp); |
@@ -43,9 +45,9 @@ void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); | |||
43 | struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t); | 45 | struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t); |
44 | void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove); | 46 | void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove); |
45 | int lpfc_linkdown(struct lpfc_hba *); | 47 | int lpfc_linkdown(struct lpfc_hba *); |
48 | void lpfc_port_link_failure(struct lpfc_vport *); | ||
46 | void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); | 49 | void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); |
47 | 50 | ||
48 | void lpfc_mbx_cmpl_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *); | ||
49 | void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 51 | void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
50 | void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *); | 52 | void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *); |
51 | void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 53 | void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
@@ -66,15 +68,15 @@ int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, | |||
66 | void lpfc_nlp_init(struct lpfc_vport *, struct lpfc_nodelist *, uint32_t); | 68 | void lpfc_nlp_init(struct lpfc_vport *, struct lpfc_nodelist *, uint32_t); |
67 | struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); | 69 | struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); |
68 | int lpfc_nlp_put(struct lpfc_nodelist *); | 70 | int lpfc_nlp_put(struct lpfc_nodelist *); |
71 | int lpfc_nlp_not_used(struct lpfc_nodelist *ndlp); | ||
69 | struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_vport *, uint32_t); | 72 | struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_vport *, uint32_t); |
70 | void lpfc_disc_list_loopmap(struct lpfc_vport *); | 73 | void lpfc_disc_list_loopmap(struct lpfc_vport *); |
71 | void lpfc_disc_start(struct lpfc_vport *); | 74 | void lpfc_disc_start(struct lpfc_vport *); |
72 | void lpfc_disc_flush_list(struct lpfc_vport *); | ||
73 | void lpfc_cleanup_discovery_resources(struct lpfc_vport *); | 75 | void lpfc_cleanup_discovery_resources(struct lpfc_vport *); |
76 | void lpfc_cleanup(struct lpfc_vport *); | ||
74 | void lpfc_disc_timeout(unsigned long); | 77 | void lpfc_disc_timeout(unsigned long); |
75 | 78 | ||
76 | struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); | 79 | struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); |
77 | struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); | ||
78 | 80 | ||
79 | void lpfc_worker_wake_up(struct lpfc_hba *); | 81 | void lpfc_worker_wake_up(struct lpfc_hba *); |
80 | int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); | 82 | int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); |
@@ -82,17 +84,17 @@ int lpfc_do_work(void *); | |||
82 | int lpfc_disc_state_machine(struct lpfc_vport *, struct lpfc_nodelist *, void *, | 84 | int lpfc_disc_state_machine(struct lpfc_vport *, struct lpfc_nodelist *, void *, |
83 | uint32_t); | 85 | uint32_t); |
84 | 86 | ||
85 | void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *, | ||
86 | struct lpfc_nodelist *); | ||
87 | void lpfc_do_scr_ns_plogi(struct lpfc_hba *, struct lpfc_vport *); | 87 | void lpfc_do_scr_ns_plogi(struct lpfc_hba *, struct lpfc_vport *); |
88 | int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *, | 88 | int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *, |
89 | struct serv_parm *, uint32_t); | 89 | struct serv_parm *, uint32_t); |
90 | int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *); | 90 | int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *); |
91 | void lpfc_more_plogi(struct lpfc_vport *); | ||
92 | void lpfc_more_adisc(struct lpfc_vport *); | ||
93 | void lpfc_end_rscn(struct lpfc_vport *); | ||
91 | int lpfc_els_chk_latt(struct lpfc_vport *); | 94 | int lpfc_els_chk_latt(struct lpfc_vport *); |
92 | int lpfc_els_abort_flogi(struct lpfc_hba *); | 95 | int lpfc_els_abort_flogi(struct lpfc_hba *); |
93 | int lpfc_initial_flogi(struct lpfc_vport *); | 96 | int lpfc_initial_flogi(struct lpfc_vport *); |
94 | int lpfc_initial_fdisc(struct lpfc_vport *); | 97 | int lpfc_initial_fdisc(struct lpfc_vport *); |
95 | int lpfc_issue_els_fdisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); | ||
96 | int lpfc_issue_els_plogi(struct lpfc_vport *, uint32_t, uint8_t); | 98 | int lpfc_issue_els_plogi(struct lpfc_vport *, uint32_t, uint8_t); |
97 | int lpfc_issue_els_prli(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); | 99 | int lpfc_issue_els_prli(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); |
98 | int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); | 100 | int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); |
@@ -112,7 +114,6 @@ int lpfc_els_rsp_prli_acc(struct lpfc_vport *, struct lpfc_iocbq *, | |||
112 | void lpfc_cancel_retry_delay_tmo(struct lpfc_vport *, struct lpfc_nodelist *); | 114 | void lpfc_cancel_retry_delay_tmo(struct lpfc_vport *, struct lpfc_nodelist *); |
113 | void lpfc_els_retry_delay(unsigned long); | 115 | void lpfc_els_retry_delay(unsigned long); |
114 | void lpfc_els_retry_delay_handler(struct lpfc_nodelist *); | 116 | void lpfc_els_retry_delay_handler(struct lpfc_nodelist *); |
115 | void lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *); | ||
116 | void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, | 117 | void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, |
117 | struct lpfc_iocbq *); | 118 | struct lpfc_iocbq *); |
118 | int lpfc_els_handle_rscn(struct lpfc_vport *); | 119 | int lpfc_els_handle_rscn(struct lpfc_vport *); |
@@ -124,7 +125,6 @@ int lpfc_els_disc_adisc(struct lpfc_vport *); | |||
124 | int lpfc_els_disc_plogi(struct lpfc_vport *); | 125 | int lpfc_els_disc_plogi(struct lpfc_vport *); |
125 | void lpfc_els_timeout(unsigned long); | 126 | void lpfc_els_timeout(unsigned long); |
126 | void lpfc_els_timeout_handler(struct lpfc_vport *); | 127 | void lpfc_els_timeout_handler(struct lpfc_vport *); |
127 | void lpfc_hb_timeout(unsigned long); | ||
128 | void lpfc_hb_timeout_handler(struct lpfc_hba *); | 128 | void lpfc_hb_timeout_handler(struct lpfc_hba *); |
129 | 129 | ||
130 | void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, | 130 | void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, |
@@ -142,7 +142,6 @@ void lpfc_hba_init(struct lpfc_hba *, uint32_t *); | |||
142 | int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int); | 142 | int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int); |
143 | void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); | 143 | void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); |
144 | int lpfc_online(struct lpfc_hba *); | 144 | int lpfc_online(struct lpfc_hba *); |
145 | void lpfc_block_mgmt_io(struct lpfc_hba *); | ||
146 | void lpfc_unblock_mgmt_io(struct lpfc_hba *); | 145 | void lpfc_unblock_mgmt_io(struct lpfc_hba *); |
147 | void lpfc_offline_prep(struct lpfc_hba *); | 146 | void lpfc_offline_prep(struct lpfc_hba *); |
148 | void lpfc_offline(struct lpfc_hba *); | 147 | void lpfc_offline(struct lpfc_hba *); |
@@ -165,7 +164,6 @@ int lpfc_mbox_tmo_val(struct lpfc_hba *, int); | |||
165 | 164 | ||
166 | void lpfc_config_hbq(struct lpfc_hba *, uint32_t, struct lpfc_hbq_init *, | 165 | void lpfc_config_hbq(struct lpfc_hba *, uint32_t, struct lpfc_hbq_init *, |
167 | uint32_t , LPFC_MBOXQ_t *); | 166 | uint32_t , LPFC_MBOXQ_t *); |
168 | struct lpfc_hbq_entry * lpfc_sli_next_hbq_slot(struct lpfc_hba *, uint32_t); | ||
169 | struct hbq_dmabuf *lpfc_els_hbq_alloc(struct lpfc_hba *); | 167 | struct hbq_dmabuf *lpfc_els_hbq_alloc(struct lpfc_hba *); |
170 | void lpfc_els_hbq_free(struct lpfc_hba *, struct hbq_dmabuf *); | 168 | void lpfc_els_hbq_free(struct lpfc_hba *, struct hbq_dmabuf *); |
171 | 169 | ||
@@ -178,7 +176,6 @@ void lpfc_poll_start_timer(struct lpfc_hba * phba); | |||
178 | void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba); | 176 | void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba); |
179 | struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); | 177 | struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); |
180 | void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); | 178 | void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); |
181 | void __lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); | ||
182 | uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); | 179 | uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); |
183 | 180 | ||
184 | void lpfc_reset_barrier(struct lpfc_hba * phba); | 181 | void lpfc_reset_barrier(struct lpfc_hba * phba); |
@@ -204,11 +201,14 @@ int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *, | |||
204 | struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *, | 201 | struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *, |
205 | struct lpfc_sli_ring *, | 202 | struct lpfc_sli_ring *, |
206 | dma_addr_t); | 203 | dma_addr_t); |
204 | |||
205 | uint32_t lpfc_sli_get_buffer_tag(struct lpfc_hba *); | ||
206 | struct lpfc_dmabuf * lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *, | ||
207 | struct lpfc_sli_ring *, uint32_t ); | ||
208 | |||
207 | int lpfc_sli_hbq_count(void); | 209 | int lpfc_sli_hbq_count(void); |
208 | int lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *, uint32_t); | ||
209 | int lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *, uint32_t); | 210 | int lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *, uint32_t); |
210 | void lpfc_sli_hbqbuf_free_all(struct lpfc_hba *); | 211 | void lpfc_sli_hbqbuf_free_all(struct lpfc_hba *); |
211 | struct hbq_dmabuf *lpfc_sli_hbqbuf_find(struct lpfc_hba *, uint32_t); | ||
212 | int lpfc_sli_hbq_size(void); | 212 | int lpfc_sli_hbq_size(void); |
213 | int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *, | 213 | int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *, |
214 | struct lpfc_iocbq *); | 214 | struct lpfc_iocbq *); |
@@ -219,9 +219,6 @@ int lpfc_sli_abort_iocb(struct lpfc_vport *, struct lpfc_sli_ring *, uint16_t, | |||
219 | void lpfc_mbox_timeout(unsigned long); | 219 | void lpfc_mbox_timeout(unsigned long); |
220 | void lpfc_mbox_timeout_handler(struct lpfc_hba *); | 220 | void lpfc_mbox_timeout_handler(struct lpfc_hba *); |
221 | 221 | ||
222 | struct lpfc_nodelist *__lpfc_find_node(struct lpfc_vport *, node_filter, | ||
223 | void *); | ||
224 | struct lpfc_nodelist *lpfc_find_node(struct lpfc_vport *, node_filter, void *); | ||
225 | struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t); | 222 | struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t); |
226 | struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *, | 223 | struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *, |
227 | struct lpfc_name *); | 224 | struct lpfc_name *); |
@@ -260,6 +257,7 @@ extern struct scsi_host_template lpfc_vport_template; | |||
260 | extern struct fc_function_template lpfc_transport_functions; | 257 | extern struct fc_function_template lpfc_transport_functions; |
261 | extern struct fc_function_template lpfc_vport_transport_functions; | 258 | extern struct fc_function_template lpfc_vport_transport_functions; |
262 | extern int lpfc_sli_mode; | 259 | extern int lpfc_sli_mode; |
260 | extern int lpfc_enable_npiv; | ||
263 | 261 | ||
264 | int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t); | 262 | int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t); |
265 | void lpfc_terminate_rport_io(struct fc_rport *); | 263 | void lpfc_terminate_rport_io(struct fc_rport *); |
@@ -281,11 +279,8 @@ extern void lpfc_debugfs_slow_ring_trc(struct lpfc_hba *, char *, uint32_t, | |||
281 | extern struct lpfc_hbq_init *lpfc_hbq_defs[]; | 279 | extern struct lpfc_hbq_init *lpfc_hbq_defs[]; |
282 | 280 | ||
283 | /* Interface exported by fabric iocb scheduler */ | 281 | /* Interface exported by fabric iocb scheduler */ |
284 | int lpfc_issue_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *); | ||
285 | void lpfc_fabric_abort_vport(struct lpfc_vport *); | ||
286 | void lpfc_fabric_abort_nport(struct lpfc_nodelist *); | 282 | void lpfc_fabric_abort_nport(struct lpfc_nodelist *); |
287 | void lpfc_fabric_abort_hba(struct lpfc_hba *); | 283 | void lpfc_fabric_abort_hba(struct lpfc_hba *); |
288 | void lpfc_fabric_abort_flogi(struct lpfc_hba *); | ||
289 | void lpfc_fabric_block_timeout(unsigned long); | 284 | void lpfc_fabric_block_timeout(unsigned long); |
290 | void lpfc_unblock_fabric_iocbs(struct lpfc_hba *); | 285 | void lpfc_unblock_fabric_iocbs(struct lpfc_hba *); |
291 | void lpfc_adjust_queue_depth(struct lpfc_hba *); | 286 | void lpfc_adjust_queue_depth(struct lpfc_hba *); |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index c701e4d611a9..92441ce610ed 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -19,7 +19,7 @@ | |||
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Fibre Channel SCSI LAN Device Driver CT support | 22 | * Fibre Channel SCSI LAN Device Driver CT support: FC Generic Services FC-GS |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/blkdev.h> | 25 | #include <linux/blkdev.h> |
@@ -57,45 +57,27 @@ | |||
57 | 57 | ||
58 | static char *lpfc_release_version = LPFC_DRIVER_VERSION; | 58 | static char *lpfc_release_version = LPFC_DRIVER_VERSION; |
59 | 59 | ||
60 | /* | ||
61 | * lpfc_ct_unsol_event | ||
62 | */ | ||
63 | static void | 60 | static void |
64 | lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | 61 | lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, |
65 | struct lpfc_dmabuf *mp, uint32_t size) | 62 | struct lpfc_dmabuf *mp, uint32_t size) |
66 | { | 63 | { |
67 | if (!mp) { | 64 | if (!mp) { |
68 | printk(KERN_ERR "%s (%d): Unsolited CT, no buffer, " | 65 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
69 | "piocbq = %p, status = x%x, mp = %p, size = %d\n", | 66 | "0146 Ignoring unsolicted CT No HBQ " |
70 | __FUNCTION__, __LINE__, | 67 | "status = x%x\n", |
71 | piocbq, piocbq->iocb.ulpStatus, mp, size); | 68 | piocbq->iocb.ulpStatus); |
72 | } | 69 | } |
73 | 70 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | |
74 | printk(KERN_ERR "%s (%d): Ignoring unsolicted CT piocbq = %p, " | 71 | "0145 Ignoring unsolicted CT HBQ Size:%d " |
75 | "buffer = %p, size = %d, status = x%x\n", | 72 | "status = x%x\n", |
76 | __FUNCTION__, __LINE__, | 73 | size, piocbq->iocb.ulpStatus); |
77 | piocbq, mp, size, | ||
78 | piocbq->iocb.ulpStatus); | ||
79 | |||
80 | } | 74 | } |
81 | 75 | ||
82 | static void | 76 | static void |
83 | lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | 77 | lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, |
84 | struct lpfc_dmabuf *mp, uint32_t size) | 78 | struct lpfc_dmabuf *mp, uint32_t size) |
85 | { | 79 | { |
86 | if (!mp) { | 80 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size); |
87 | printk(KERN_ERR "%s (%d): Unsolited CT, no " | ||
88 | "HBQ buffer, piocbq = %p, status = x%x\n", | ||
89 | __FUNCTION__, __LINE__, | ||
90 | piocbq, piocbq->iocb.ulpStatus); | ||
91 | } else { | ||
92 | lpfc_ct_unsol_buffer(phba, piocbq, mp, size); | ||
93 | printk(KERN_ERR "%s (%d): Ignoring unsolicted CT " | ||
94 | "piocbq = %p, buffer = %p, size = %d, " | ||
95 | "status = x%x\n", | ||
96 | __FUNCTION__, __LINE__, | ||
97 | piocbq, mp, size, piocbq->iocb.ulpStatus); | ||
98 | } | ||
99 | } | 81 | } |
100 | 82 | ||
101 | void | 83 | void |
@@ -109,11 +91,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
109 | struct lpfc_iocbq *iocbq; | 91 | struct lpfc_iocbq *iocbq; |
110 | dma_addr_t paddr; | 92 | dma_addr_t paddr; |
111 | uint32_t size; | 93 | uint32_t size; |
112 | struct lpfc_dmabuf *bdeBuf1 = piocbq->context2; | 94 | struct list_head head; |
113 | struct lpfc_dmabuf *bdeBuf2 = piocbq->context3; | 95 | struct lpfc_dmabuf *bdeBuf; |
114 | |||
115 | piocbq->context2 = NULL; | ||
116 | piocbq->context3 = NULL; | ||
117 | 96 | ||
118 | if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) { | 97 | if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) { |
119 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); | 98 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); |
@@ -122,7 +101,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
122 | /* Not enough posted buffers; Try posting more buffers */ | 101 | /* Not enough posted buffers; Try posting more buffers */ |
123 | phba->fc_stat.NoRcvBuf++; | 102 | phba->fc_stat.NoRcvBuf++; |
124 | if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) | 103 | if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) |
125 | lpfc_post_buffer(phba, pring, 0, 1); | 104 | lpfc_post_buffer(phba, pring, 2, 1); |
126 | return; | 105 | return; |
127 | } | 106 | } |
128 | 107 | ||
@@ -133,38 +112,34 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
133 | return; | 112 | return; |
134 | 113 | ||
135 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | 114 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { |
136 | list_for_each_entry(iocbq, &piocbq->list, list) { | 115 | INIT_LIST_HEAD(&head); |
116 | list_add_tail(&head, &piocbq->list); | ||
117 | list_for_each_entry(iocbq, &head, list) { | ||
137 | icmd = &iocbq->iocb; | 118 | icmd = &iocbq->iocb; |
138 | if (icmd->ulpBdeCount == 0) { | 119 | if (icmd->ulpBdeCount == 0) |
139 | printk(KERN_ERR "%s (%d): Unsolited CT, no " | ||
140 | "BDE, iocbq = %p, status = x%x\n", | ||
141 | __FUNCTION__, __LINE__, | ||
142 | iocbq, iocbq->iocb.ulpStatus); | ||
143 | continue; | 120 | continue; |
144 | } | 121 | bdeBuf = iocbq->context2; |
145 | 122 | iocbq->context2 = NULL; | |
146 | size = icmd->un.cont64[0].tus.f.bdeSize; | 123 | size = icmd->un.cont64[0].tus.f.bdeSize; |
147 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf1, size); | 124 | lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size); |
148 | lpfc_in_buf_free(phba, bdeBuf1); | 125 | lpfc_in_buf_free(phba, bdeBuf); |
149 | if (icmd->ulpBdeCount == 2) { | 126 | if (icmd->ulpBdeCount == 2) { |
150 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf2, | 127 | bdeBuf = iocbq->context3; |
151 | size); | 128 | iocbq->context3 = NULL; |
152 | lpfc_in_buf_free(phba, bdeBuf2); | 129 | size = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize; |
130 | lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, | ||
131 | size); | ||
132 | lpfc_in_buf_free(phba, bdeBuf); | ||
153 | } | 133 | } |
154 | } | 134 | } |
135 | list_del(&head); | ||
155 | } else { | 136 | } else { |
156 | struct lpfc_iocbq *next; | 137 | struct lpfc_iocbq *next; |
157 | 138 | ||
158 | list_for_each_entry_safe(iocbq, next, &piocbq->list, list) { | 139 | list_for_each_entry_safe(iocbq, next, &piocbq->list, list) { |
159 | icmd = &iocbq->iocb; | 140 | icmd = &iocbq->iocb; |
160 | if (icmd->ulpBdeCount == 0) { | 141 | if (icmd->ulpBdeCount == 0) |
161 | printk(KERN_ERR "%s (%d): Unsolited CT, no " | 142 | lpfc_ct_unsol_buffer(phba, piocbq, NULL, 0); |
162 | "BDE, iocbq = %p, status = x%x\n", | ||
163 | __FUNCTION__, __LINE__, | ||
164 | iocbq, iocbq->iocb.ulpStatus); | ||
165 | continue; | ||
166 | } | ||
167 | |||
168 | for (i = 0; i < icmd->ulpBdeCount; i++) { | 143 | for (i = 0; i < icmd->ulpBdeCount; i++) { |
169 | paddr = getPaddr(icmd->un.cont64[i].addrHigh, | 144 | paddr = getPaddr(icmd->un.cont64[i].addrHigh, |
170 | icmd->un.cont64[i].addrLow); | 145 | icmd->un.cont64[i].addrLow); |
@@ -176,6 +151,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
176 | } | 151 | } |
177 | list_del(&iocbq->list); | 152 | list_del(&iocbq->list); |
178 | lpfc_sli_release_iocbq(phba, iocbq); | 153 | lpfc_sli_release_iocbq(phba, iocbq); |
154 | lpfc_post_buffer(phba, pring, i, 1); | ||
179 | } | 155 | } |
180 | } | 156 | } |
181 | } | 157 | } |
@@ -203,7 +179,7 @@ lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl, | |||
203 | struct lpfc_dmabuf *mp; | 179 | struct lpfc_dmabuf *mp; |
204 | int cnt, i = 0; | 180 | int cnt, i = 0; |
205 | 181 | ||
206 | /* We get chucks of FCELSSIZE */ | 182 | /* We get chunks of FCELSSIZE */ |
207 | cnt = size > FCELSSIZE ? FCELSSIZE: size; | 183 | cnt = size > FCELSSIZE ? FCELSSIZE: size; |
208 | 184 | ||
209 | while (size) { | 185 | while (size) { |
@@ -426,6 +402,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
426 | 402 | ||
427 | lpfc_set_disctmo(vport); | 403 | lpfc_set_disctmo(vport); |
428 | vport->num_disc_nodes = 0; | 404 | vport->num_disc_nodes = 0; |
405 | vport->fc_ns_retry = 0; | ||
429 | 406 | ||
430 | 407 | ||
431 | list_add_tail(&head, &mp->list); | 408 | list_add_tail(&head, &mp->list); |
@@ -458,7 +435,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
458 | ((lpfc_find_vport_by_did(phba, Did) == NULL) || | 435 | ((lpfc_find_vport_by_did(phba, Did) == NULL) || |
459 | vport->cfg_peer_port_login)) { | 436 | vport->cfg_peer_port_login)) { |
460 | if ((vport->port_type != LPFC_NPIV_PORT) || | 437 | if ((vport->port_type != LPFC_NPIV_PORT) || |
461 | (vport->fc_flag & FC_RFF_NOT_SUPPORTED) || | 438 | (!(vport->ct_flags & FC_CT_RFF_ID)) || |
462 | (!vport->cfg_restrict_login)) { | 439 | (!vport->cfg_restrict_login)) { |
463 | ndlp = lpfc_setup_disc_node(vport, Did); | 440 | ndlp = lpfc_setup_disc_node(vport, Did); |
464 | if (ndlp) { | 441 | if (ndlp) { |
@@ -506,7 +483,17 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
506 | Did, vport->fc_flag, | 483 | Did, vport->fc_flag, |
507 | vport->fc_rscn_id_cnt); | 484 | vport->fc_rscn_id_cnt); |
508 | 485 | ||
509 | if (lpfc_ns_cmd(vport, | 486 | /* This NPortID was previously |
487 | * a FCP target, * Don't even | ||
488 | * bother to send GFF_ID. | ||
489 | */ | ||
490 | ndlp = lpfc_findnode_did(vport, | ||
491 | Did); | ||
492 | if (ndlp && (ndlp->nlp_type & | ||
493 | NLP_FCP_TARGET)) | ||
494 | lpfc_setup_disc_node | ||
495 | (vport, Did); | ||
496 | else if (lpfc_ns_cmd(vport, | ||
510 | SLI_CTNS_GFF_ID, | 497 | SLI_CTNS_GFF_ID, |
511 | 0, Did) == 0) | 498 | 0, Did) == 0) |
512 | vport->num_disc_nodes++; | 499 | vport->num_disc_nodes++; |
@@ -554,7 +541,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
554 | struct lpfc_dmabuf *outp; | 541 | struct lpfc_dmabuf *outp; |
555 | struct lpfc_sli_ct_request *CTrsp; | 542 | struct lpfc_sli_ct_request *CTrsp; |
556 | struct lpfc_nodelist *ndlp; | 543 | struct lpfc_nodelist *ndlp; |
557 | int rc; | 544 | int rc, retry; |
558 | 545 | ||
559 | /* First save ndlp, before we overwrite it */ | 546 | /* First save ndlp, before we overwrite it */ |
560 | ndlp = cmdiocb->context_un.ndlp; | 547 | ndlp = cmdiocb->context_un.ndlp; |
@@ -574,7 +561,6 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
574 | if (vport->load_flag & FC_UNLOADING) | 561 | if (vport->load_flag & FC_UNLOADING) |
575 | goto out; | 562 | goto out; |
576 | 563 | ||
577 | |||
578 | if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { | 564 | if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { |
579 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 565 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
580 | "0216 Link event during NS query\n"); | 566 | "0216 Link event during NS query\n"); |
@@ -585,14 +571,35 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
585 | if (irsp->ulpStatus) { | 571 | if (irsp->ulpStatus) { |
586 | /* Check for retry */ | 572 | /* Check for retry */ |
587 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { | 573 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { |
588 | if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || | 574 | retry = 1; |
589 | (irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)) | 575 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { |
576 | switch (irsp->un.ulpWord[4]) { | ||
577 | case IOERR_NO_RESOURCES: | ||
578 | /* We don't increment the retry | ||
579 | * count for this case. | ||
580 | */ | ||
581 | break; | ||
582 | case IOERR_LINK_DOWN: | ||
583 | case IOERR_SLI_ABORTED: | ||
584 | case IOERR_SLI_DOWN: | ||
585 | retry = 0; | ||
586 | break; | ||
587 | default: | ||
588 | vport->fc_ns_retry++; | ||
589 | } | ||
590 | } | ||
591 | else | ||
590 | vport->fc_ns_retry++; | 592 | vport->fc_ns_retry++; |
591 | /* CT command is being retried */ | 593 | |
592 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, | 594 | if (retry) { |
595 | /* CT command is being retried */ | ||
596 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, | ||
593 | vport->fc_ns_retry, 0); | 597 | vport->fc_ns_retry, 0); |
594 | if (rc == 0) | 598 | if (rc == 0) { |
595 | goto out; | 599 | /* success */ |
600 | goto out; | ||
601 | } | ||
602 | } | ||
596 | } | 603 | } |
597 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 604 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
598 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 605 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -698,7 +705,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
698 | struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1; | 705 | struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1; |
699 | struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2; | 706 | struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2; |
700 | struct lpfc_sli_ct_request *CTrsp; | 707 | struct lpfc_sli_ct_request *CTrsp; |
701 | int did; | 708 | int did, rc, retry; |
702 | uint8_t fbits; | 709 | uint8_t fbits; |
703 | struct lpfc_nodelist *ndlp; | 710 | struct lpfc_nodelist *ndlp; |
704 | 711 | ||
@@ -729,6 +736,39 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
729 | } | 736 | } |
730 | } | 737 | } |
731 | else { | 738 | else { |
739 | /* Check for retry */ | ||
740 | if (cmdiocb->retry < LPFC_MAX_NS_RETRY) { | ||
741 | retry = 1; | ||
742 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { | ||
743 | switch (irsp->un.ulpWord[4]) { | ||
744 | case IOERR_NO_RESOURCES: | ||
745 | /* We don't increment the retry | ||
746 | * count for this case. | ||
747 | */ | ||
748 | break; | ||
749 | case IOERR_LINK_DOWN: | ||
750 | case IOERR_SLI_ABORTED: | ||
751 | case IOERR_SLI_DOWN: | ||
752 | retry = 0; | ||
753 | break; | ||
754 | default: | ||
755 | cmdiocb->retry++; | ||
756 | } | ||
757 | } | ||
758 | else | ||
759 | cmdiocb->retry++; | ||
760 | |||
761 | if (retry) { | ||
762 | /* CT command is being retried */ | ||
763 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GFF_ID, | ||
764 | cmdiocb->retry, did); | ||
765 | if (rc == 0) { | ||
766 | /* success */ | ||
767 | lpfc_ct_free_iocb(phba, cmdiocb); | ||
768 | return; | ||
769 | } | ||
770 | } | ||
771 | } | ||
732 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 772 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
733 | "0267 NameServer GFF Rsp " | 773 | "0267 NameServer GFF Rsp " |
734 | "x%x Error (%d %d) Data: x%x x%x\n", | 774 | "x%x Error (%d %d) Data: x%x x%x\n", |
@@ -778,8 +818,8 @@ out: | |||
778 | 818 | ||
779 | 819 | ||
780 | static void | 820 | static void |
781 | lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 821 | lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
782 | struct lpfc_iocbq *rspiocb) | 822 | struct lpfc_iocbq *rspiocb) |
783 | { | 823 | { |
784 | struct lpfc_vport *vport = cmdiocb->vport; | 824 | struct lpfc_vport *vport = cmdiocb->vport; |
785 | struct lpfc_dmabuf *inp; | 825 | struct lpfc_dmabuf *inp; |
@@ -809,7 +849,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
809 | 849 | ||
810 | /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */ | 850 | /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */ |
811 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 851 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
812 | "0209 RFT request completes, latt %d, " | 852 | "0209 CT Request completes, latt %d, " |
813 | "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n", | 853 | "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n", |
814 | latt, irsp->ulpStatus, | 854 | latt, irsp->ulpStatus, |
815 | CTrsp->CommandResponse.bits.CmdRsp, | 855 | CTrsp->CommandResponse.bits.CmdRsp, |
@@ -848,10 +888,44 @@ out: | |||
848 | } | 888 | } |
849 | 889 | ||
850 | static void | 890 | static void |
891 | lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | ||
892 | struct lpfc_iocbq *rspiocb) | ||
893 | { | ||
894 | IOCB_t *irsp = &rspiocb->iocb; | ||
895 | struct lpfc_vport *vport = cmdiocb->vport; | ||
896 | |||
897 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { | ||
898 | struct lpfc_dmabuf *outp; | ||
899 | struct lpfc_sli_ct_request *CTrsp; | ||
900 | |||
901 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
902 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
903 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
904 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) | ||
905 | vport->ct_flags |= FC_CT_RFT_ID; | ||
906 | } | ||
907 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
908 | return; | ||
909 | } | ||
910 | |||
911 | static void | ||
851 | lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 912 | lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
852 | struct lpfc_iocbq *rspiocb) | 913 | struct lpfc_iocbq *rspiocb) |
853 | { | 914 | { |
854 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 915 | IOCB_t *irsp = &rspiocb->iocb; |
916 | struct lpfc_vport *vport = cmdiocb->vport; | ||
917 | |||
918 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { | ||
919 | struct lpfc_dmabuf *outp; | ||
920 | struct lpfc_sli_ct_request *CTrsp; | ||
921 | |||
922 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
923 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
924 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
925 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) | ||
926 | vport->ct_flags |= FC_CT_RNN_ID; | ||
927 | } | ||
928 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
855 | return; | 929 | return; |
856 | } | 930 | } |
857 | 931 | ||
@@ -859,7 +933,20 @@ static void | |||
859 | lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 933 | lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
860 | struct lpfc_iocbq *rspiocb) | 934 | struct lpfc_iocbq *rspiocb) |
861 | { | 935 | { |
862 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 936 | IOCB_t *irsp = &rspiocb->iocb; |
937 | struct lpfc_vport *vport = cmdiocb->vport; | ||
938 | |||
939 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { | ||
940 | struct lpfc_dmabuf *outp; | ||
941 | struct lpfc_sli_ct_request *CTrsp; | ||
942 | |||
943 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
944 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
945 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
946 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) | ||
947 | vport->ct_flags |= FC_CT_RSPN_ID; | ||
948 | } | ||
949 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
863 | return; | 950 | return; |
864 | } | 951 | } |
865 | 952 | ||
@@ -867,7 +954,32 @@ static void | |||
867 | lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 954 | lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
868 | struct lpfc_iocbq *rspiocb) | 955 | struct lpfc_iocbq *rspiocb) |
869 | { | 956 | { |
870 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 957 | IOCB_t *irsp = &rspiocb->iocb; |
958 | struct lpfc_vport *vport = cmdiocb->vport; | ||
959 | |||
960 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { | ||
961 | struct lpfc_dmabuf *outp; | ||
962 | struct lpfc_sli_ct_request *CTrsp; | ||
963 | |||
964 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
965 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
966 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
967 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) | ||
968 | vport->ct_flags |= FC_CT_RSNN_NN; | ||
969 | } | ||
970 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
971 | return; | ||
972 | } | ||
973 | |||
974 | static void | ||
975 | lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | ||
976 | struct lpfc_iocbq *rspiocb) | ||
977 | { | ||
978 | struct lpfc_vport *vport = cmdiocb->vport; | ||
979 | |||
980 | /* even if it fails we will act as though it succeeded. */ | ||
981 | vport->ct_flags = 0; | ||
982 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
871 | return; | 983 | return; |
872 | } | 984 | } |
873 | 985 | ||
@@ -878,10 +990,17 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
878 | IOCB_t *irsp = &rspiocb->iocb; | 990 | IOCB_t *irsp = &rspiocb->iocb; |
879 | struct lpfc_vport *vport = cmdiocb->vport; | 991 | struct lpfc_vport *vport = cmdiocb->vport; |
880 | 992 | ||
881 | if (irsp->ulpStatus != IOSTAT_SUCCESS) | 993 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { |
882 | vport->fc_flag |= FC_RFF_NOT_SUPPORTED; | 994 | struct lpfc_dmabuf *outp; |
995 | struct lpfc_sli_ct_request *CTrsp; | ||
883 | 996 | ||
884 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 997 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; |
998 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
999 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
1000 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) | ||
1001 | vport->ct_flags |= FC_CT_RFF_ID; | ||
1002 | } | ||
1003 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
885 | return; | 1004 | return; |
886 | } | 1005 | } |
887 | 1006 | ||
@@ -1001,6 +1120,8 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1001 | bpl->tus.f.bdeSize = RSPN_REQUEST_SZ; | 1120 | bpl->tus.f.bdeSize = RSPN_REQUEST_SZ; |
1002 | else if (cmdcode == SLI_CTNS_RSNN_NN) | 1121 | else if (cmdcode == SLI_CTNS_RSNN_NN) |
1003 | bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; | 1122 | bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; |
1123 | else if (cmdcode == SLI_CTNS_DA_ID) | ||
1124 | bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ; | ||
1004 | else if (cmdcode == SLI_CTNS_RFF_ID) | 1125 | else if (cmdcode == SLI_CTNS_RFF_ID) |
1005 | bpl->tus.f.bdeSize = RFF_REQUEST_SZ; | 1126 | bpl->tus.f.bdeSize = RFF_REQUEST_SZ; |
1006 | else | 1127 | else |
@@ -1029,31 +1150,34 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1029 | case SLI_CTNS_GFF_ID: | 1150 | case SLI_CTNS_GFF_ID: |
1030 | CtReq->CommandResponse.bits.CmdRsp = | 1151 | CtReq->CommandResponse.bits.CmdRsp = |
1031 | be16_to_cpu(SLI_CTNS_GFF_ID); | 1152 | be16_to_cpu(SLI_CTNS_GFF_ID); |
1032 | CtReq->un.gff.PortId = be32_to_cpu(context); | 1153 | CtReq->un.gff.PortId = cpu_to_be32(context); |
1033 | cmpl = lpfc_cmpl_ct_cmd_gff_id; | 1154 | cmpl = lpfc_cmpl_ct_cmd_gff_id; |
1034 | break; | 1155 | break; |
1035 | 1156 | ||
1036 | case SLI_CTNS_RFT_ID: | 1157 | case SLI_CTNS_RFT_ID: |
1158 | vport->ct_flags &= ~FC_CT_RFT_ID; | ||
1037 | CtReq->CommandResponse.bits.CmdRsp = | 1159 | CtReq->CommandResponse.bits.CmdRsp = |
1038 | be16_to_cpu(SLI_CTNS_RFT_ID); | 1160 | be16_to_cpu(SLI_CTNS_RFT_ID); |
1039 | CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID); | 1161 | CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID); |
1040 | CtReq->un.rft.fcpReg = 1; | 1162 | CtReq->un.rft.fcpReg = 1; |
1041 | cmpl = lpfc_cmpl_ct_cmd_rft_id; | 1163 | cmpl = lpfc_cmpl_ct_cmd_rft_id; |
1042 | break; | 1164 | break; |
1043 | 1165 | ||
1044 | case SLI_CTNS_RNN_ID: | 1166 | case SLI_CTNS_RNN_ID: |
1167 | vport->ct_flags &= ~FC_CT_RNN_ID; | ||
1045 | CtReq->CommandResponse.bits.CmdRsp = | 1168 | CtReq->CommandResponse.bits.CmdRsp = |
1046 | be16_to_cpu(SLI_CTNS_RNN_ID); | 1169 | be16_to_cpu(SLI_CTNS_RNN_ID); |
1047 | CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID); | 1170 | CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID); |
1048 | memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, | 1171 | memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, |
1049 | sizeof (struct lpfc_name)); | 1172 | sizeof (struct lpfc_name)); |
1050 | cmpl = lpfc_cmpl_ct_cmd_rnn_id; | 1173 | cmpl = lpfc_cmpl_ct_cmd_rnn_id; |
1051 | break; | 1174 | break; |
1052 | 1175 | ||
1053 | case SLI_CTNS_RSPN_ID: | 1176 | case SLI_CTNS_RSPN_ID: |
1177 | vport->ct_flags &= ~FC_CT_RSPN_ID; | ||
1054 | CtReq->CommandResponse.bits.CmdRsp = | 1178 | CtReq->CommandResponse.bits.CmdRsp = |
1055 | be16_to_cpu(SLI_CTNS_RSPN_ID); | 1179 | be16_to_cpu(SLI_CTNS_RSPN_ID); |
1056 | CtReq->un.rspn.PortId = be32_to_cpu(vport->fc_myDID); | 1180 | CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID); |
1057 | size = sizeof(CtReq->un.rspn.symbname); | 1181 | size = sizeof(CtReq->un.rspn.symbname); |
1058 | CtReq->un.rspn.len = | 1182 | CtReq->un.rspn.len = |
1059 | lpfc_vport_symbolic_port_name(vport, | 1183 | lpfc_vport_symbolic_port_name(vport, |
@@ -1061,6 +1185,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1061 | cmpl = lpfc_cmpl_ct_cmd_rspn_id; | 1185 | cmpl = lpfc_cmpl_ct_cmd_rspn_id; |
1062 | break; | 1186 | break; |
1063 | case SLI_CTNS_RSNN_NN: | 1187 | case SLI_CTNS_RSNN_NN: |
1188 | vport->ct_flags &= ~FC_CT_RSNN_NN; | ||
1064 | CtReq->CommandResponse.bits.CmdRsp = | 1189 | CtReq->CommandResponse.bits.CmdRsp = |
1065 | be16_to_cpu(SLI_CTNS_RSNN_NN); | 1190 | be16_to_cpu(SLI_CTNS_RSNN_NN); |
1066 | memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, | 1191 | memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, |
@@ -1071,11 +1196,18 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1071 | CtReq->un.rsnn.symbname, size); | 1196 | CtReq->un.rsnn.symbname, size); |
1072 | cmpl = lpfc_cmpl_ct_cmd_rsnn_nn; | 1197 | cmpl = lpfc_cmpl_ct_cmd_rsnn_nn; |
1073 | break; | 1198 | break; |
1199 | case SLI_CTNS_DA_ID: | ||
1200 | /* Implement DA_ID Nameserver request */ | ||
1201 | CtReq->CommandResponse.bits.CmdRsp = | ||
1202 | be16_to_cpu(SLI_CTNS_DA_ID); | ||
1203 | CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID); | ||
1204 | cmpl = lpfc_cmpl_ct_cmd_da_id; | ||
1205 | break; | ||
1074 | case SLI_CTNS_RFF_ID: | 1206 | case SLI_CTNS_RFF_ID: |
1075 | vport->fc_flag &= ~FC_RFF_NOT_SUPPORTED; | 1207 | vport->ct_flags &= ~FC_CT_RFF_ID; |
1076 | CtReq->CommandResponse.bits.CmdRsp = | 1208 | CtReq->CommandResponse.bits.CmdRsp = |
1077 | be16_to_cpu(SLI_CTNS_RFF_ID); | 1209 | be16_to_cpu(SLI_CTNS_RFF_ID); |
1078 | CtReq->un.rff.PortId = be32_to_cpu(vport->fc_myDID);; | 1210 | CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);; |
1079 | CtReq->un.rff.fbits = FC4_FEATURE_INIT; | 1211 | CtReq->un.rff.fbits = FC4_FEATURE_INIT; |
1080 | CtReq->un.rff.type_code = FC_FCP_DATA; | 1212 | CtReq->un.rff.type_code = FC_FCP_DATA; |
1081 | cmpl = lpfc_cmpl_ct_cmd_rff_id; | 1213 | cmpl = lpfc_cmpl_ct_cmd_rff_id; |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index d6a98bc970ff..783d1eea13ef 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include "lpfc_crtn.h" | 43 | #include "lpfc_crtn.h" |
44 | #include "lpfc_vport.h" | 44 | #include "lpfc_vport.h" |
45 | #include "lpfc_version.h" | 45 | #include "lpfc_version.h" |
46 | #include "lpfc_compat.h" | ||
46 | #include "lpfc_debugfs.h" | 47 | #include "lpfc_debugfs.h" |
47 | 48 | ||
48 | #ifdef CONFIG_LPFC_DEBUG_FS | 49 | #ifdef CONFIG_LPFC_DEBUG_FS |
@@ -75,18 +76,18 @@ module_param(lpfc_debugfs_enable, int, 0); | |||
75 | MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services"); | 76 | MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services"); |
76 | 77 | ||
77 | /* This MUST be a power of 2 */ | 78 | /* This MUST be a power of 2 */ |
78 | static int lpfc_debugfs_max_disc_trc = 0; | 79 | static int lpfc_debugfs_max_disc_trc; |
79 | module_param(lpfc_debugfs_max_disc_trc, int, 0); | 80 | module_param(lpfc_debugfs_max_disc_trc, int, 0); |
80 | MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc, | 81 | MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc, |
81 | "Set debugfs discovery trace depth"); | 82 | "Set debugfs discovery trace depth"); |
82 | 83 | ||
83 | /* This MUST be a power of 2 */ | 84 | /* This MUST be a power of 2 */ |
84 | static int lpfc_debugfs_max_slow_ring_trc = 0; | 85 | static int lpfc_debugfs_max_slow_ring_trc; |
85 | module_param(lpfc_debugfs_max_slow_ring_trc, int, 0); | 86 | module_param(lpfc_debugfs_max_slow_ring_trc, int, 0); |
86 | MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc, | 87 | MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc, |
87 | "Set debugfs slow ring trace depth"); | 88 | "Set debugfs slow ring trace depth"); |
88 | 89 | ||
89 | static int lpfc_debugfs_mask_disc_trc = 0; | 90 | int lpfc_debugfs_mask_disc_trc; |
90 | module_param(lpfc_debugfs_mask_disc_trc, int, 0); | 91 | module_param(lpfc_debugfs_mask_disc_trc, int, 0); |
91 | MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, | 92 | MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, |
92 | "Set debugfs discovery trace mask"); | 93 | "Set debugfs discovery trace mask"); |
@@ -100,8 +101,11 @@ MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, | |||
100 | #define LPFC_NODELIST_SIZE 8192 | 101 | #define LPFC_NODELIST_SIZE 8192 |
101 | #define LPFC_NODELIST_ENTRY_SIZE 120 | 102 | #define LPFC_NODELIST_ENTRY_SIZE 120 |
102 | 103 | ||
103 | /* dumpslim output buffer size */ | 104 | /* dumpHBASlim output buffer size */ |
104 | #define LPFC_DUMPSLIM_SIZE 4096 | 105 | #define LPFC_DUMPHBASLIM_SIZE 4096 |
106 | |||
107 | /* dumpHostSlim output buffer size */ | ||
108 | #define LPFC_DUMPHOSTSLIM_SIZE 4096 | ||
105 | 109 | ||
106 | /* hbqinfo output buffer size */ | 110 | /* hbqinfo output buffer size */ |
107 | #define LPFC_HBQINFO_SIZE 8192 | 111 | #define LPFC_HBQINFO_SIZE 8192 |
@@ -243,16 +247,17 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) | |||
243 | raw_index = phba->hbq_get[i]; | 247 | raw_index = phba->hbq_get[i]; |
244 | getidx = le32_to_cpu(raw_index); | 248 | getidx = le32_to_cpu(raw_index); |
245 | len += snprintf(buf+len, size-len, | 249 | len += snprintf(buf+len, size-len, |
246 | "entrys:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n", | 250 | "entrys:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n", |
247 | hbqs->entry_count, hbqs->hbqPutIdx, hbqs->next_hbqPutIdx, | 251 | hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx, |
248 | hbqs->local_hbqGetIdx, getidx); | 252 | hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx); |
249 | 253 | ||
250 | hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt; | 254 | hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt; |
251 | for (j=0; j<hbqs->entry_count; j++) { | 255 | for (j=0; j<hbqs->entry_count; j++) { |
252 | len += snprintf(buf+len, size-len, | 256 | len += snprintf(buf+len, size-len, |
253 | "%03d: %08x %04x %05x ", j, | 257 | "%03d: %08x %04x %05x ", j, |
254 | hbqe->bde.addrLow, hbqe->bde.tus.w, hbqe->buffer_tag); | 258 | le32_to_cpu(hbqe->bde.addrLow), |
255 | 259 | le32_to_cpu(hbqe->bde.tus.w), | |
260 | le32_to_cpu(hbqe->buffer_tag)); | ||
256 | i = 0; | 261 | i = 0; |
257 | found = 0; | 262 | found = 0; |
258 | 263 | ||
@@ -276,7 +281,7 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) | |||
276 | list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) { | 281 | list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) { |
277 | hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); | 282 | hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); |
278 | phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); | 283 | phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); |
279 | if (phys == hbqe->bde.addrLow) { | 284 | if (phys == le32_to_cpu(hbqe->bde.addrLow)) { |
280 | len += snprintf(buf+len, size-len, | 285 | len += snprintf(buf+len, size-len, |
281 | "Buf%d: %p %06x\n", i, | 286 | "Buf%d: %p %06x\n", i, |
282 | hbq_buf->dbuf.virt, hbq_buf->tag); | 287 | hbq_buf->dbuf.virt, hbq_buf->tag); |
@@ -297,18 +302,58 @@ skipit: | |||
297 | return len; | 302 | return len; |
298 | } | 303 | } |
299 | 304 | ||
305 | static int lpfc_debugfs_last_hba_slim_off; | ||
306 | |||
307 | static int | ||
308 | lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size) | ||
309 | { | ||
310 | int len = 0; | ||
311 | int i, off; | ||
312 | uint32_t *ptr; | ||
313 | char buffer[1024]; | ||
314 | |||
315 | off = 0; | ||
316 | spin_lock_irq(&phba->hbalock); | ||
317 | |||
318 | len += snprintf(buf+len, size-len, "HBA SLIM\n"); | ||
319 | lpfc_memcpy_from_slim(buffer, | ||
320 | ((uint8_t *)phba->MBslimaddr) + lpfc_debugfs_last_hba_slim_off, | ||
321 | 1024); | ||
322 | |||
323 | ptr = (uint32_t *)&buffer[0]; | ||
324 | off = lpfc_debugfs_last_hba_slim_off; | ||
325 | |||
326 | /* Set it up for the next time */ | ||
327 | lpfc_debugfs_last_hba_slim_off += 1024; | ||
328 | if (lpfc_debugfs_last_hba_slim_off >= 4096) | ||
329 | lpfc_debugfs_last_hba_slim_off = 0; | ||
330 | |||
331 | i = 1024; | ||
332 | while (i > 0) { | ||
333 | len += snprintf(buf+len, size-len, | ||
334 | "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", | ||
335 | off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), | ||
336 | *(ptr+5), *(ptr+6), *(ptr+7)); | ||
337 | ptr += 8; | ||
338 | i -= (8 * sizeof(uint32_t)); | ||
339 | off += (8 * sizeof(uint32_t)); | ||
340 | } | ||
341 | |||
342 | spin_unlock_irq(&phba->hbalock); | ||
343 | return len; | ||
344 | } | ||
345 | |||
300 | static int | 346 | static int |
301 | lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size) | 347 | lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) |
302 | { | 348 | { |
303 | int len = 0; | 349 | int len = 0; |
304 | int cnt, i, off; | 350 | int i, off; |
305 | uint32_t word0, word1, word2, word3; | 351 | uint32_t word0, word1, word2, word3; |
306 | uint32_t *ptr; | 352 | uint32_t *ptr; |
307 | struct lpfc_pgp *pgpp; | 353 | struct lpfc_pgp *pgpp; |
308 | struct lpfc_sli *psli = &phba->sli; | 354 | struct lpfc_sli *psli = &phba->sli; |
309 | struct lpfc_sli_ring *pring; | 355 | struct lpfc_sli_ring *pring; |
310 | 356 | ||
311 | cnt = LPFC_DUMPSLIM_SIZE; | ||
312 | off = 0; | 357 | off = 0; |
313 | spin_lock_irq(&phba->hbalock); | 358 | spin_lock_irq(&phba->hbalock); |
314 | 359 | ||
@@ -620,7 +665,34 @@ out: | |||
620 | } | 665 | } |
621 | 666 | ||
622 | static int | 667 | static int |
623 | lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file) | 668 | lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file) |
669 | { | ||
670 | struct lpfc_hba *phba = inode->i_private; | ||
671 | struct lpfc_debug *debug; | ||
672 | int rc = -ENOMEM; | ||
673 | |||
674 | debug = kmalloc(sizeof(*debug), GFP_KERNEL); | ||
675 | if (!debug) | ||
676 | goto out; | ||
677 | |||
678 | /* Round to page boundry */ | ||
679 | debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL); | ||
680 | if (!debug->buffer) { | ||
681 | kfree(debug); | ||
682 | goto out; | ||
683 | } | ||
684 | |||
685 | debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer, | ||
686 | LPFC_DUMPHBASLIM_SIZE); | ||
687 | file->private_data = debug; | ||
688 | |||
689 | rc = 0; | ||
690 | out: | ||
691 | return rc; | ||
692 | } | ||
693 | |||
694 | static int | ||
695 | lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file) | ||
624 | { | 696 | { |
625 | struct lpfc_hba *phba = inode->i_private; | 697 | struct lpfc_hba *phba = inode->i_private; |
626 | struct lpfc_debug *debug; | 698 | struct lpfc_debug *debug; |
@@ -631,14 +703,14 @@ lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file) | |||
631 | goto out; | 703 | goto out; |
632 | 704 | ||
633 | /* Round to page boundry */ | 705 | /* Round to page boundry */ |
634 | debug->buffer = kmalloc(LPFC_DUMPSLIM_SIZE, GFP_KERNEL); | 706 | debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL); |
635 | if (!debug->buffer) { | 707 | if (!debug->buffer) { |
636 | kfree(debug); | 708 | kfree(debug); |
637 | goto out; | 709 | goto out; |
638 | } | 710 | } |
639 | 711 | ||
640 | debug->len = lpfc_debugfs_dumpslim_data(phba, debug->buffer, | 712 | debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer, |
641 | LPFC_DUMPSLIM_SIZE); | 713 | LPFC_DUMPHOSTSLIM_SIZE); |
642 | file->private_data = debug; | 714 | file->private_data = debug; |
643 | 715 | ||
644 | rc = 0; | 716 | rc = 0; |
@@ -741,10 +813,19 @@ static struct file_operations lpfc_debugfs_op_hbqinfo = { | |||
741 | .release = lpfc_debugfs_release, | 813 | .release = lpfc_debugfs_release, |
742 | }; | 814 | }; |
743 | 815 | ||
744 | #undef lpfc_debugfs_op_dumpslim | 816 | #undef lpfc_debugfs_op_dumpHBASlim |
745 | static struct file_operations lpfc_debugfs_op_dumpslim = { | 817 | static struct file_operations lpfc_debugfs_op_dumpHBASlim = { |
818 | .owner = THIS_MODULE, | ||
819 | .open = lpfc_debugfs_dumpHBASlim_open, | ||
820 | .llseek = lpfc_debugfs_lseek, | ||
821 | .read = lpfc_debugfs_read, | ||
822 | .release = lpfc_debugfs_release, | ||
823 | }; | ||
824 | |||
825 | #undef lpfc_debugfs_op_dumpHostSlim | ||
826 | static struct file_operations lpfc_debugfs_op_dumpHostSlim = { | ||
746 | .owner = THIS_MODULE, | 827 | .owner = THIS_MODULE, |
747 | .open = lpfc_debugfs_dumpslim_open, | 828 | .open = lpfc_debugfs_dumpHostSlim_open, |
748 | .llseek = lpfc_debugfs_lseek, | 829 | .llseek = lpfc_debugfs_lseek, |
749 | .read = lpfc_debugfs_read, | 830 | .read = lpfc_debugfs_read, |
750 | .release = lpfc_debugfs_release, | 831 | .release = lpfc_debugfs_release, |
@@ -812,15 +893,27 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) | |||
812 | goto debug_failed; | 893 | goto debug_failed; |
813 | } | 894 | } |
814 | 895 | ||
815 | /* Setup dumpslim */ | 896 | /* Setup dumpHBASlim */ |
816 | snprintf(name, sizeof(name), "dumpslim"); | 897 | snprintf(name, sizeof(name), "dumpHBASlim"); |
817 | phba->debug_dumpslim = | 898 | phba->debug_dumpHBASlim = |
899 | debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, | ||
900 | phba->hba_debugfs_root, | ||
901 | phba, &lpfc_debugfs_op_dumpHBASlim); | ||
902 | if (!phba->debug_dumpHBASlim) { | ||
903 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | ||
904 | "0409 Cannot create debugfs dumpHBASlim\n"); | ||
905 | goto debug_failed; | ||
906 | } | ||
907 | |||
908 | /* Setup dumpHostSlim */ | ||
909 | snprintf(name, sizeof(name), "dumpHostSlim"); | ||
910 | phba->debug_dumpHostSlim = | ||
818 | debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, | 911 | debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, |
819 | phba->hba_debugfs_root, | 912 | phba->hba_debugfs_root, |
820 | phba, &lpfc_debugfs_op_dumpslim); | 913 | phba, &lpfc_debugfs_op_dumpHostSlim); |
821 | if (!phba->debug_dumpslim) { | 914 | if (!phba->debug_dumpHostSlim) { |
822 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 915 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
823 | "0409 Cannot create debugfs dumpslim\n"); | 916 | "0409 Cannot create debugfs dumpHostSlim\n"); |
824 | goto debug_failed; | 917 | goto debug_failed; |
825 | } | 918 | } |
826 | 919 | ||
@@ -970,9 +1063,13 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) | |||
970 | debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */ | 1063 | debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */ |
971 | phba->debug_hbqinfo = NULL; | 1064 | phba->debug_hbqinfo = NULL; |
972 | } | 1065 | } |
973 | if (phba->debug_dumpslim) { | 1066 | if (phba->debug_dumpHBASlim) { |
974 | debugfs_remove(phba->debug_dumpslim); /* dumpslim */ | 1067 | debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */ |
975 | phba->debug_dumpslim = NULL; | 1068 | phba->debug_dumpHBASlim = NULL; |
1069 | } | ||
1070 | if (phba->debug_dumpHostSlim) { | ||
1071 | debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */ | ||
1072 | phba->debug_dumpHostSlim = NULL; | ||
976 | } | 1073 | } |
977 | if (phba->slow_ring_trc) { | 1074 | if (phba->slow_ring_trc) { |
978 | kfree(phba->slow_ring_trc); | 1075 | kfree(phba->slow_ring_trc); |
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index aacac9ac5381..cfe81c50529a 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h | |||
@@ -36,7 +36,6 @@ enum lpfc_work_type { | |||
36 | LPFC_EVT_WARM_START, | 36 | LPFC_EVT_WARM_START, |
37 | LPFC_EVT_KILL, | 37 | LPFC_EVT_KILL, |
38 | LPFC_EVT_ELS_RETRY, | 38 | LPFC_EVT_ELS_RETRY, |
39 | LPFC_EVT_DEV_LOSS_DELAY, | ||
40 | LPFC_EVT_DEV_LOSS, | 39 | LPFC_EVT_DEV_LOSS, |
41 | }; | 40 | }; |
42 | 41 | ||
@@ -92,6 +91,7 @@ struct lpfc_nodelist { | |||
92 | #define NLP_LOGO_SND 0x100 /* sent LOGO request for this entry */ | 91 | #define NLP_LOGO_SND 0x100 /* sent LOGO request for this entry */ |
93 | #define NLP_RNID_SND 0x400 /* sent RNID request for this entry */ | 92 | #define NLP_RNID_SND 0x400 /* sent RNID request for this entry */ |
94 | #define NLP_ELS_SND_MASK 0x7e0 /* sent ELS request for this entry */ | 93 | #define NLP_ELS_SND_MASK 0x7e0 /* sent ELS request for this entry */ |
94 | #define NLP_DEFER_RM 0x10000 /* Remove this ndlp if no longer used */ | ||
95 | #define NLP_DELAY_TMO 0x20000 /* delay timeout is running for node */ | 95 | #define NLP_DELAY_TMO 0x20000 /* delay timeout is running for node */ |
96 | #define NLP_NPR_2B_DISC 0x40000 /* node is included in num_disc_nodes */ | 96 | #define NLP_NPR_2B_DISC 0x40000 /* node is included in num_disc_nodes */ |
97 | #define NLP_RCV_PLOGI 0x80000 /* Rcv'ed PLOGI from remote system */ | 97 | #define NLP_RCV_PLOGI 0x80000 /* Rcv'ed PLOGI from remote system */ |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 8085900635d4..c6b739dc6bc3 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * more details, a copy of which can be found in the file COPYING * | 18 | * more details, a copy of which can be found in the file COPYING * |
19 | * included with this package. * | 19 | * included with this package. * |
20 | *******************************************************************/ | 20 | *******************************************************************/ |
21 | 21 | /* See Fibre Channel protocol T11 FC-LS for details */ | |
22 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
@@ -42,6 +42,14 @@ static int lpfc_els_retry(struct lpfc_hba *, struct lpfc_iocbq *, | |||
42 | struct lpfc_iocbq *); | 42 | struct lpfc_iocbq *); |
43 | static void lpfc_cmpl_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *, | 43 | static void lpfc_cmpl_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *, |
44 | struct lpfc_iocbq *); | 44 | struct lpfc_iocbq *); |
45 | static void lpfc_fabric_abort_vport(struct lpfc_vport *vport); | ||
46 | static int lpfc_issue_els_fdisc(struct lpfc_vport *vport, | ||
47 | struct lpfc_nodelist *ndlp, uint8_t retry); | ||
48 | static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba, | ||
49 | struct lpfc_iocbq *iocb); | ||
50 | static void lpfc_register_new_vport(struct lpfc_hba *phba, | ||
51 | struct lpfc_vport *vport, | ||
52 | struct lpfc_nodelist *ndlp); | ||
45 | 53 | ||
46 | static int lpfc_max_els_tries = 3; | 54 | static int lpfc_max_els_tries = 3; |
47 | 55 | ||
@@ -109,14 +117,11 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
109 | 117 | ||
110 | /* fill in BDEs for command */ | 118 | /* fill in BDEs for command */ |
111 | /* Allocate buffer for command payload */ | 119 | /* Allocate buffer for command payload */ |
112 | if (((pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL)) == 0) || | 120 | pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); |
113 | ((pcmd->virt = lpfc_mbuf_alloc(phba, | 121 | if (pcmd) |
114 | MEM_PRI, &(pcmd->phys))) == 0)) { | 122 | pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys); |
115 | kfree(pcmd); | 123 | if (!pcmd || !pcmd->virt) |
116 | 124 | goto els_iocb_free_pcmb_exit; | |
117 | lpfc_sli_release_iocbq(phba, elsiocb); | ||
118 | return NULL; | ||
119 | } | ||
120 | 125 | ||
121 | INIT_LIST_HEAD(&pcmd->list); | 126 | INIT_LIST_HEAD(&pcmd->list); |
122 | 127 | ||
@@ -126,13 +131,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
126 | if (prsp) | 131 | if (prsp) |
127 | prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, | 132 | prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, |
128 | &prsp->phys); | 133 | &prsp->phys); |
129 | if (prsp == 0 || prsp->virt == 0) { | 134 | if (!prsp || !prsp->virt) |
130 | kfree(prsp); | 135 | goto els_iocb_free_prsp_exit; |
131 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); | ||
132 | kfree(pcmd); | ||
133 | lpfc_sli_release_iocbq(phba, elsiocb); | ||
134 | return NULL; | ||
135 | } | ||
136 | INIT_LIST_HEAD(&prsp->list); | 136 | INIT_LIST_HEAD(&prsp->list); |
137 | } else { | 137 | } else { |
138 | prsp = NULL; | 138 | prsp = NULL; |
@@ -143,15 +143,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
143 | if (pbuflist) | 143 | if (pbuflist) |
144 | pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, | 144 | pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, |
145 | &pbuflist->phys); | 145 | &pbuflist->phys); |
146 | if (pbuflist == 0 || pbuflist->virt == 0) { | 146 | if (!pbuflist || !pbuflist->virt) |
147 | lpfc_sli_release_iocbq(phba, elsiocb); | 147 | goto els_iocb_free_pbuf_exit; |
148 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); | ||
149 | lpfc_mbuf_free(phba, prsp->virt, prsp->phys); | ||
150 | kfree(pcmd); | ||
151 | kfree(prsp); | ||
152 | kfree(pbuflist); | ||
153 | return NULL; | ||
154 | } | ||
155 | 148 | ||
156 | INIT_LIST_HEAD(&pbuflist->list); | 149 | INIT_LIST_HEAD(&pbuflist->list); |
157 | 150 | ||
@@ -196,7 +189,10 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
196 | bpl->tus.w = le32_to_cpu(bpl->tus.w); | 189 | bpl->tus.w = le32_to_cpu(bpl->tus.w); |
197 | } | 190 | } |
198 | 191 | ||
192 | /* prevent preparing iocb with NULL ndlp reference */ | ||
199 | elsiocb->context1 = lpfc_nlp_get(ndlp); | 193 | elsiocb->context1 = lpfc_nlp_get(ndlp); |
194 | if (!elsiocb->context1) | ||
195 | goto els_iocb_free_pbuf_exit; | ||
200 | elsiocb->context2 = pcmd; | 196 | elsiocb->context2 = pcmd; |
201 | elsiocb->context3 = pbuflist; | 197 | elsiocb->context3 = pbuflist; |
202 | elsiocb->retry = retry; | 198 | elsiocb->retry = retry; |
@@ -222,8 +218,20 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
222 | cmdSize); | 218 | cmdSize); |
223 | } | 219 | } |
224 | return elsiocb; | 220 | return elsiocb; |
225 | } | ||
226 | 221 | ||
222 | els_iocb_free_pbuf_exit: | ||
223 | lpfc_mbuf_free(phba, prsp->virt, prsp->phys); | ||
224 | kfree(pbuflist); | ||
225 | |||
226 | els_iocb_free_prsp_exit: | ||
227 | lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); | ||
228 | kfree(prsp); | ||
229 | |||
230 | els_iocb_free_pcmb_exit: | ||
231 | kfree(pcmd); | ||
232 | lpfc_sli_release_iocbq(phba, elsiocb); | ||
233 | return NULL; | ||
234 | } | ||
227 | 235 | ||
228 | static int | 236 | static int |
229 | lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) | 237 | lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) |
@@ -234,40 +242,53 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) | |||
234 | struct lpfc_nodelist *ndlp; | 242 | struct lpfc_nodelist *ndlp; |
235 | struct serv_parm *sp; | 243 | struct serv_parm *sp; |
236 | int rc; | 244 | int rc; |
245 | int err = 0; | ||
237 | 246 | ||
238 | sp = &phba->fc_fabparam; | 247 | sp = &phba->fc_fabparam; |
239 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | 248 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
240 | if (!ndlp) | 249 | if (!ndlp) { |
250 | err = 1; | ||
241 | goto fail; | 251 | goto fail; |
252 | } | ||
242 | 253 | ||
243 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 254 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
244 | if (!mbox) | 255 | if (!mbox) { |
256 | err = 2; | ||
245 | goto fail; | 257 | goto fail; |
258 | } | ||
246 | 259 | ||
247 | vport->port_state = LPFC_FABRIC_CFG_LINK; | 260 | vport->port_state = LPFC_FABRIC_CFG_LINK; |
248 | lpfc_config_link(phba, mbox); | 261 | lpfc_config_link(phba, mbox); |
249 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 262 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
250 | mbox->vport = vport; | 263 | mbox->vport = vport; |
251 | 264 | ||
252 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); | 265 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
253 | if (rc == MBX_NOT_FINISHED) | 266 | if (rc == MBX_NOT_FINISHED) { |
267 | err = 3; | ||
254 | goto fail_free_mbox; | 268 | goto fail_free_mbox; |
269 | } | ||
255 | 270 | ||
256 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 271 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
257 | if (!mbox) | 272 | if (!mbox) { |
273 | err = 4; | ||
258 | goto fail; | 274 | goto fail; |
275 | } | ||
259 | rc = lpfc_reg_login(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox, | 276 | rc = lpfc_reg_login(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox, |
260 | 0); | 277 | 0); |
261 | if (rc) | 278 | if (rc) { |
279 | err = 5; | ||
262 | goto fail_free_mbox; | 280 | goto fail_free_mbox; |
281 | } | ||
263 | 282 | ||
264 | mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; | 283 | mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; |
265 | mbox->vport = vport; | 284 | mbox->vport = vport; |
266 | mbox->context2 = lpfc_nlp_get(ndlp); | 285 | mbox->context2 = lpfc_nlp_get(ndlp); |
267 | 286 | ||
268 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); | 287 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
269 | if (rc == MBX_NOT_FINISHED) | 288 | if (rc == MBX_NOT_FINISHED) { |
289 | err = 6; | ||
270 | goto fail_issue_reg_login; | 290 | goto fail_issue_reg_login; |
291 | } | ||
271 | 292 | ||
272 | return 0; | 293 | return 0; |
273 | 294 | ||
@@ -282,7 +303,7 @@ fail_free_mbox: | |||
282 | fail: | 303 | fail: |
283 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 304 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
284 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 305 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
285 | "0249 Cannot issue Register Fabric login\n"); | 306 | "0249 Cannot issue Register Fabric login: Err %d\n", err); |
286 | return -ENXIO; | 307 | return -ENXIO; |
287 | } | 308 | } |
288 | 309 | ||
@@ -370,11 +391,12 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
370 | } | 391 | } |
371 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { | 392 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { |
372 | lpfc_mbx_unreg_vpi(vport); | 393 | lpfc_mbx_unreg_vpi(vport); |
394 | spin_lock_irq(shost->host_lock); | ||
373 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 395 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
396 | spin_unlock_irq(shost->host_lock); | ||
374 | } | 397 | } |
375 | } | 398 | } |
376 | 399 | ||
377 | ndlp->nlp_sid = irsp->un.ulpWord[4] & Mask_DID; | ||
378 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); | 400 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); |
379 | 401 | ||
380 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED && | 402 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED && |
@@ -429,8 +451,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
429 | 451 | ||
430 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 452 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
431 | mbox->vport = vport; | 453 | mbox->vport = vport; |
432 | rc = lpfc_sli_issue_mbox(phba, mbox, | 454 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
433 | MBX_NOWAIT | MBX_STOP_IOCB); | ||
434 | if (rc == MBX_NOT_FINISHED) { | 455 | if (rc == MBX_NOT_FINISHED) { |
435 | mempool_free(mbox, phba->mbox_mem_pool); | 456 | mempool_free(mbox, phba->mbox_mem_pool); |
436 | goto fail; | 457 | goto fail; |
@@ -463,6 +484,9 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
463 | lpfc_nlp_put(ndlp); | 484 | lpfc_nlp_put(ndlp); |
464 | } | 485 | } |
465 | 486 | ||
487 | /* If we are pt2pt with another NPort, force NPIV off! */ | ||
488 | phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; | ||
489 | |||
466 | spin_lock_irq(shost->host_lock); | 490 | spin_lock_irq(shost->host_lock); |
467 | vport->fc_flag |= FC_PT2PT; | 491 | vport->fc_flag |= FC_PT2PT; |
468 | spin_unlock_irq(shost->host_lock); | 492 | spin_unlock_irq(shost->host_lock); |
@@ -488,6 +512,9 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
488 | 512 | ||
489 | /* Check to see if link went down during discovery */ | 513 | /* Check to see if link went down during discovery */ |
490 | if (lpfc_els_chk_latt(vport)) { | 514 | if (lpfc_els_chk_latt(vport)) { |
515 | /* One additional decrement on node reference count to | ||
516 | * trigger the release of the node | ||
517 | */ | ||
491 | lpfc_nlp_put(ndlp); | 518 | lpfc_nlp_put(ndlp); |
492 | goto out; | 519 | goto out; |
493 | } | 520 | } |
@@ -562,8 +589,13 @@ flogifail: | |||
562 | 589 | ||
563 | /* Start discovery */ | 590 | /* Start discovery */ |
564 | lpfc_disc_start(vport); | 591 | lpfc_disc_start(vport); |
592 | } else if (((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || | ||
593 | ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) && | ||
594 | (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) && | ||
595 | (phba->link_state != LPFC_CLEAR_LA)) { | ||
596 | /* If FLOGI failed enable link interrupt. */ | ||
597 | lpfc_issue_clear_la(phba, vport); | ||
565 | } | 598 | } |
566 | |||
567 | out: | 599 | out: |
568 | lpfc_els_free_iocb(phba, cmdiocb); | 600 | lpfc_els_free_iocb(phba, cmdiocb); |
569 | } | 601 | } |
@@ -685,6 +717,9 @@ lpfc_initial_flogi(struct lpfc_vport *vport) | |||
685 | struct lpfc_hba *phba = vport->phba; | 717 | struct lpfc_hba *phba = vport->phba; |
686 | struct lpfc_nodelist *ndlp; | 718 | struct lpfc_nodelist *ndlp; |
687 | 719 | ||
720 | vport->port_state = LPFC_FLOGI; | ||
721 | lpfc_set_disctmo(vport); | ||
722 | |||
688 | /* First look for the Fabric ndlp */ | 723 | /* First look for the Fabric ndlp */ |
689 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | 724 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
690 | if (!ndlp) { | 725 | if (!ndlp) { |
@@ -696,7 +731,11 @@ lpfc_initial_flogi(struct lpfc_vport *vport) | |||
696 | } else { | 731 | } else { |
697 | lpfc_dequeue_node(vport, ndlp); | 732 | lpfc_dequeue_node(vport, ndlp); |
698 | } | 733 | } |
734 | |||
699 | if (lpfc_issue_els_flogi(vport, ndlp, 0)) { | 735 | if (lpfc_issue_els_flogi(vport, ndlp, 0)) { |
736 | /* This decrement of reference count to node shall kick off | ||
737 | * the release of the node. | ||
738 | */ | ||
700 | lpfc_nlp_put(ndlp); | 739 | lpfc_nlp_put(ndlp); |
701 | } | 740 | } |
702 | return 1; | 741 | return 1; |
@@ -720,11 +759,16 @@ lpfc_initial_fdisc(struct lpfc_vport *vport) | |||
720 | lpfc_dequeue_node(vport, ndlp); | 759 | lpfc_dequeue_node(vport, ndlp); |
721 | } | 760 | } |
722 | if (lpfc_issue_els_fdisc(vport, ndlp, 0)) { | 761 | if (lpfc_issue_els_fdisc(vport, ndlp, 0)) { |
762 | /* decrement node reference count to trigger the release of | ||
763 | * the node. | ||
764 | */ | ||
723 | lpfc_nlp_put(ndlp); | 765 | lpfc_nlp_put(ndlp); |
766 | return 0; | ||
724 | } | 767 | } |
725 | return 1; | 768 | return 1; |
726 | } | 769 | } |
727 | static void | 770 | |
771 | void | ||
728 | lpfc_more_plogi(struct lpfc_vport *vport) | 772 | lpfc_more_plogi(struct lpfc_vport *vport) |
729 | { | 773 | { |
730 | int sentplogi; | 774 | int sentplogi; |
@@ -752,6 +796,8 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
752 | { | 796 | { |
753 | struct lpfc_vport *vport = ndlp->vport; | 797 | struct lpfc_vport *vport = ndlp->vport; |
754 | struct lpfc_nodelist *new_ndlp; | 798 | struct lpfc_nodelist *new_ndlp; |
799 | struct lpfc_rport_data *rdata; | ||
800 | struct fc_rport *rport; | ||
755 | struct serv_parm *sp; | 801 | struct serv_parm *sp; |
756 | uint8_t name[sizeof(struct lpfc_name)]; | 802 | uint8_t name[sizeof(struct lpfc_name)]; |
757 | uint32_t rc; | 803 | uint32_t rc; |
@@ -788,11 +834,34 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
788 | lpfc_unreg_rpi(vport, new_ndlp); | 834 | lpfc_unreg_rpi(vport, new_ndlp); |
789 | new_ndlp->nlp_DID = ndlp->nlp_DID; | 835 | new_ndlp->nlp_DID = ndlp->nlp_DID; |
790 | new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; | 836 | new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; |
837 | |||
838 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) | ||
839 | new_ndlp->nlp_flag |= NLP_NPR_2B_DISC; | ||
840 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | ||
841 | |||
791 | lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state); | 842 | lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state); |
792 | 843 | ||
793 | /* Move this back to NPR state */ | 844 | /* Move this back to NPR state */ |
794 | if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) | 845 | if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) { |
846 | /* The new_ndlp is replacing ndlp totally, so we need | ||
847 | * to put ndlp on UNUSED list and try to free it. | ||
848 | */ | ||
849 | |||
850 | /* Fix up the rport accordingly */ | ||
851 | rport = ndlp->rport; | ||
852 | if (rport) { | ||
853 | rdata = rport->dd_data; | ||
854 | if (rdata->pnode == ndlp) { | ||
855 | lpfc_nlp_put(ndlp); | ||
856 | ndlp->rport = NULL; | ||
857 | rdata->pnode = lpfc_nlp_get(new_ndlp); | ||
858 | new_ndlp->rport = rport; | ||
859 | } | ||
860 | new_ndlp->nlp_type = ndlp->nlp_type; | ||
861 | } | ||
862 | |||
795 | lpfc_drop_node(vport, ndlp); | 863 | lpfc_drop_node(vport, ndlp); |
864 | } | ||
796 | else { | 865 | else { |
797 | lpfc_unreg_rpi(vport, ndlp); | 866 | lpfc_unreg_rpi(vport, ndlp); |
798 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | 867 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ |
@@ -801,6 +870,27 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
801 | return new_ndlp; | 870 | return new_ndlp; |
802 | } | 871 | } |
803 | 872 | ||
873 | void | ||
874 | lpfc_end_rscn(struct lpfc_vport *vport) | ||
875 | { | ||
876 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
877 | |||
878 | if (vport->fc_flag & FC_RSCN_MODE) { | ||
879 | /* | ||
880 | * Check to see if more RSCNs came in while we were | ||
881 | * processing this one. | ||
882 | */ | ||
883 | if (vport->fc_rscn_id_cnt || | ||
884 | (vport->fc_flag & FC_RSCN_DISCOVERY) != 0) | ||
885 | lpfc_els_handle_rscn(vport); | ||
886 | else { | ||
887 | spin_lock_irq(shost->host_lock); | ||
888 | vport->fc_flag &= ~FC_RSCN_MODE; | ||
889 | spin_unlock_irq(shost->host_lock); | ||
890 | } | ||
891 | } | ||
892 | } | ||
893 | |||
804 | static void | 894 | static void |
805 | lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 895 | lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
806 | struct lpfc_iocbq *rspiocb) | 896 | struct lpfc_iocbq *rspiocb) |
@@ -871,13 +961,6 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
871 | goto out; | 961 | goto out; |
872 | } | 962 | } |
873 | /* PLOGI failed */ | 963 | /* PLOGI failed */ |
874 | if (ndlp->nlp_DID == NameServer_DID) { | ||
875 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
876 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
877 | "0250 Nameserver login error: " | ||
878 | "0x%x / 0x%x\n", | ||
879 | irsp->ulpStatus, irsp->un.ulpWord[4]); | ||
880 | } | ||
881 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 964 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
882 | if (lpfc_error_lost_link(irsp)) { | 965 | if (lpfc_error_lost_link(irsp)) { |
883 | rc = NLP_STE_FREED_NODE; | 966 | rc = NLP_STE_FREED_NODE; |
@@ -905,20 +988,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
905 | spin_unlock_irq(shost->host_lock); | 988 | spin_unlock_irq(shost->host_lock); |
906 | 989 | ||
907 | lpfc_can_disctmo(vport); | 990 | lpfc_can_disctmo(vport); |
908 | if (vport->fc_flag & FC_RSCN_MODE) { | 991 | lpfc_end_rscn(vport); |
909 | /* | ||
910 | * Check to see if more RSCNs came in while | ||
911 | * we were processing this one. | ||
912 | */ | ||
913 | if ((vport->fc_rscn_id_cnt == 0) && | ||
914 | (!(vport->fc_flag & FC_RSCN_DISCOVERY))) { | ||
915 | spin_lock_irq(shost->host_lock); | ||
916 | vport->fc_flag &= ~FC_RSCN_MODE; | ||
917 | spin_unlock_irq(shost->host_lock); | ||
918 | } else { | ||
919 | lpfc_els_handle_rscn(vport); | ||
920 | } | ||
921 | } | ||
922 | } | 992 | } |
923 | } | 993 | } |
924 | 994 | ||
@@ -933,6 +1003,7 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | |||
933 | struct lpfc_hba *phba = vport->phba; | 1003 | struct lpfc_hba *phba = vport->phba; |
934 | struct serv_parm *sp; | 1004 | struct serv_parm *sp; |
935 | IOCB_t *icmd; | 1005 | IOCB_t *icmd; |
1006 | struct lpfc_nodelist *ndlp; | ||
936 | struct lpfc_iocbq *elsiocb; | 1007 | struct lpfc_iocbq *elsiocb; |
937 | struct lpfc_sli_ring *pring; | 1008 | struct lpfc_sli_ring *pring; |
938 | struct lpfc_sli *psli; | 1009 | struct lpfc_sli *psli; |
@@ -943,8 +1014,11 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | |||
943 | psli = &phba->sli; | 1014 | psli = &phba->sli; |
944 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 1015 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
945 | 1016 | ||
1017 | ndlp = lpfc_findnode_did(vport, did); | ||
1018 | /* If ndlp if not NULL, we will bump the reference count on it */ | ||
1019 | |||
946 | cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); | 1020 | cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); |
947 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, NULL, did, | 1021 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, |
948 | ELS_CMD_PLOGI); | 1022 | ELS_CMD_PLOGI); |
949 | if (!elsiocb) | 1023 | if (!elsiocb) |
950 | return 1; | 1024 | return 1; |
@@ -1109,7 +1183,7 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1109 | return 0; | 1183 | return 0; |
1110 | } | 1184 | } |
1111 | 1185 | ||
1112 | static void | 1186 | void |
1113 | lpfc_more_adisc(struct lpfc_vport *vport) | 1187 | lpfc_more_adisc(struct lpfc_vport *vport) |
1114 | { | 1188 | { |
1115 | int sentadisc; | 1189 | int sentadisc; |
@@ -1134,8 +1208,6 @@ lpfc_more_adisc(struct lpfc_vport *vport) | |||
1134 | static void | 1208 | static void |
1135 | lpfc_rscn_disc(struct lpfc_vport *vport) | 1209 | lpfc_rscn_disc(struct lpfc_vport *vport) |
1136 | { | 1210 | { |
1137 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1138 | |||
1139 | lpfc_can_disctmo(vport); | 1211 | lpfc_can_disctmo(vport); |
1140 | 1212 | ||
1141 | /* RSCN discovery */ | 1213 | /* RSCN discovery */ |
@@ -1144,19 +1216,7 @@ lpfc_rscn_disc(struct lpfc_vport *vport) | |||
1144 | if (lpfc_els_disc_plogi(vport)) | 1216 | if (lpfc_els_disc_plogi(vport)) |
1145 | return; | 1217 | return; |
1146 | 1218 | ||
1147 | if (vport->fc_flag & FC_RSCN_MODE) { | 1219 | lpfc_end_rscn(vport); |
1148 | /* Check to see if more RSCNs came in while we were | ||
1149 | * processing this one. | ||
1150 | */ | ||
1151 | if ((vport->fc_rscn_id_cnt == 0) && | ||
1152 | (!(vport->fc_flag & FC_RSCN_DISCOVERY))) { | ||
1153 | spin_lock_irq(shost->host_lock); | ||
1154 | vport->fc_flag &= ~FC_RSCN_MODE; | ||
1155 | spin_unlock_irq(shost->host_lock); | ||
1156 | } else { | ||
1157 | lpfc_els_handle_rscn(vport); | ||
1158 | } | ||
1159 | } | ||
1160 | } | 1220 | } |
1161 | 1221 | ||
1162 | static void | 1222 | static void |
@@ -1413,6 +1473,13 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1413 | psli = &phba->sli; | 1473 | psli = &phba->sli; |
1414 | pring = &psli->ring[LPFC_ELS_RING]; | 1474 | pring = &psli->ring[LPFC_ELS_RING]; |
1415 | 1475 | ||
1476 | spin_lock_irq(shost->host_lock); | ||
1477 | if (ndlp->nlp_flag & NLP_LOGO_SND) { | ||
1478 | spin_unlock_irq(shost->host_lock); | ||
1479 | return 0; | ||
1480 | } | ||
1481 | spin_unlock_irq(shost->host_lock); | ||
1482 | |||
1416 | cmdsize = (2 * sizeof(uint32_t)) + sizeof(struct lpfc_name); | 1483 | cmdsize = (2 * sizeof(uint32_t)) + sizeof(struct lpfc_name); |
1417 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, | 1484 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, |
1418 | ndlp->nlp_DID, ELS_CMD_LOGO); | 1485 | ndlp->nlp_DID, ELS_CMD_LOGO); |
@@ -1499,6 +1566,9 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1499 | ndlp->nlp_DID, ELS_CMD_SCR); | 1566 | ndlp->nlp_DID, ELS_CMD_SCR); |
1500 | 1567 | ||
1501 | if (!elsiocb) { | 1568 | if (!elsiocb) { |
1569 | /* This will trigger the release of the node just | ||
1570 | * allocated | ||
1571 | */ | ||
1502 | lpfc_nlp_put(ndlp); | 1572 | lpfc_nlp_put(ndlp); |
1503 | return 1; | 1573 | return 1; |
1504 | } | 1574 | } |
@@ -1520,10 +1590,17 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1520 | phba->fc_stat.elsXmitSCR++; | 1590 | phba->fc_stat.elsXmitSCR++; |
1521 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; | 1591 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; |
1522 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1592 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
1593 | /* The additional lpfc_nlp_put will cause the following | ||
1594 | * lpfc_els_free_iocb routine to trigger the rlease of | ||
1595 | * the node. | ||
1596 | */ | ||
1523 | lpfc_nlp_put(ndlp); | 1597 | lpfc_nlp_put(ndlp); |
1524 | lpfc_els_free_iocb(phba, elsiocb); | 1598 | lpfc_els_free_iocb(phba, elsiocb); |
1525 | return 1; | 1599 | return 1; |
1526 | } | 1600 | } |
1601 | /* This will cause the callback-function lpfc_cmpl_els_cmd to | ||
1602 | * trigger the release of node. | ||
1603 | */ | ||
1527 | lpfc_nlp_put(ndlp); | 1604 | lpfc_nlp_put(ndlp); |
1528 | return 0; | 1605 | return 0; |
1529 | } | 1606 | } |
@@ -1555,6 +1632,9 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1555 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, | 1632 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, |
1556 | ndlp->nlp_DID, ELS_CMD_RNID); | 1633 | ndlp->nlp_DID, ELS_CMD_RNID); |
1557 | if (!elsiocb) { | 1634 | if (!elsiocb) { |
1635 | /* This will trigger the release of the node just | ||
1636 | * allocated | ||
1637 | */ | ||
1558 | lpfc_nlp_put(ndlp); | 1638 | lpfc_nlp_put(ndlp); |
1559 | return 1; | 1639 | return 1; |
1560 | } | 1640 | } |
@@ -1591,35 +1671,21 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1591 | phba->fc_stat.elsXmitFARPR++; | 1671 | phba->fc_stat.elsXmitFARPR++; |
1592 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; | 1672 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; |
1593 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1673 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
1674 | /* The additional lpfc_nlp_put will cause the following | ||
1675 | * lpfc_els_free_iocb routine to trigger the release of | ||
1676 | * the node. | ||
1677 | */ | ||
1594 | lpfc_nlp_put(ndlp); | 1678 | lpfc_nlp_put(ndlp); |
1595 | lpfc_els_free_iocb(phba, elsiocb); | 1679 | lpfc_els_free_iocb(phba, elsiocb); |
1596 | return 1; | 1680 | return 1; |
1597 | } | 1681 | } |
1682 | /* This will cause the callback-function lpfc_cmpl_els_cmd to | ||
1683 | * trigger the release of the node. | ||
1684 | */ | ||
1598 | lpfc_nlp_put(ndlp); | 1685 | lpfc_nlp_put(ndlp); |
1599 | return 0; | 1686 | return 0; |
1600 | } | 1687 | } |
1601 | 1688 | ||
1602 | static void | ||
1603 | lpfc_end_rscn(struct lpfc_vport *vport) | ||
1604 | { | ||
1605 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1606 | |||
1607 | if (vport->fc_flag & FC_RSCN_MODE) { | ||
1608 | /* | ||
1609 | * Check to see if more RSCNs came in while we were | ||
1610 | * processing this one. | ||
1611 | */ | ||
1612 | if (vport->fc_rscn_id_cnt || | ||
1613 | (vport->fc_flag & FC_RSCN_DISCOVERY) != 0) | ||
1614 | lpfc_els_handle_rscn(vport); | ||
1615 | else { | ||
1616 | spin_lock_irq(shost->host_lock); | ||
1617 | vport->fc_flag &= ~FC_RSCN_MODE; | ||
1618 | spin_unlock_irq(shost->host_lock); | ||
1619 | } | ||
1620 | } | ||
1621 | } | ||
1622 | |||
1623 | void | 1689 | void |
1624 | lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) | 1690 | lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) |
1625 | { | 1691 | { |
@@ -1675,7 +1741,10 @@ lpfc_els_retry_delay(unsigned long ptr) | |||
1675 | return; | 1741 | return; |
1676 | } | 1742 | } |
1677 | 1743 | ||
1678 | evtp->evt_arg1 = ndlp; | 1744 | /* We need to hold the node by incrementing the reference |
1745 | * count until the queued work is done | ||
1746 | */ | ||
1747 | evtp->evt_arg1 = lpfc_nlp_get(ndlp); | ||
1679 | evtp->evt = LPFC_EVT_ELS_RETRY; | 1748 | evtp->evt = LPFC_EVT_ELS_RETRY; |
1680 | list_add_tail(&evtp->evt_listp, &phba->work_list); | 1749 | list_add_tail(&evtp->evt_listp, &phba->work_list); |
1681 | if (phba->work_wait) | 1750 | if (phba->work_wait) |
@@ -1759,6 +1828,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1759 | uint32_t *elscmd; | 1828 | uint32_t *elscmd; |
1760 | struct ls_rjt stat; | 1829 | struct ls_rjt stat; |
1761 | int retry = 0, maxretry = lpfc_max_els_tries, delay = 0; | 1830 | int retry = 0, maxretry = lpfc_max_els_tries, delay = 0; |
1831 | int logerr = 0; | ||
1762 | uint32_t cmd = 0; | 1832 | uint32_t cmd = 0; |
1763 | uint32_t did; | 1833 | uint32_t did; |
1764 | 1834 | ||
@@ -1815,6 +1885,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1815 | break; | 1885 | break; |
1816 | 1886 | ||
1817 | case IOERR_NO_RESOURCES: | 1887 | case IOERR_NO_RESOURCES: |
1888 | logerr = 1; /* HBA out of resources */ | ||
1818 | retry = 1; | 1889 | retry = 1; |
1819 | if (cmdiocb->retry > 100) | 1890 | if (cmdiocb->retry > 100) |
1820 | delay = 100; | 1891 | delay = 100; |
@@ -1843,6 +1914,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1843 | 1914 | ||
1844 | case IOSTAT_NPORT_BSY: | 1915 | case IOSTAT_NPORT_BSY: |
1845 | case IOSTAT_FABRIC_BSY: | 1916 | case IOSTAT_FABRIC_BSY: |
1917 | logerr = 1; /* Fabric / Remote NPort out of resources */ | ||
1846 | retry = 1; | 1918 | retry = 1; |
1847 | break; | 1919 | break; |
1848 | 1920 | ||
@@ -1923,6 +1995,15 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1923 | if (did == FDMI_DID) | 1995 | if (did == FDMI_DID) |
1924 | retry = 1; | 1996 | retry = 1; |
1925 | 1997 | ||
1998 | if ((cmd == ELS_CMD_FLOGI) && | ||
1999 | (phba->fc_topology != TOPOLOGY_LOOP)) { | ||
2000 | /* FLOGI retry policy */ | ||
2001 | retry = 1; | ||
2002 | maxretry = 48; | ||
2003 | if (cmdiocb->retry >= 32) | ||
2004 | delay = 1000; | ||
2005 | } | ||
2006 | |||
1926 | if ((++cmdiocb->retry) >= maxretry) { | 2007 | if ((++cmdiocb->retry) >= maxretry) { |
1927 | phba->fc_stat.elsRetryExceeded++; | 2008 | phba->fc_stat.elsRetryExceeded++; |
1928 | retry = 0; | 2009 | retry = 0; |
@@ -2006,11 +2087,46 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2006 | } | 2087 | } |
2007 | } | 2088 | } |
2008 | /* No retry ELS command <elsCmd> to remote NPORT <did> */ | 2089 | /* No retry ELS command <elsCmd> to remote NPORT <did> */ |
2009 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 2090 | if (logerr) { |
2091 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
2092 | "0137 No retry ELS command x%x to remote " | ||
2093 | "NPORT x%x: Out of Resources: Error:x%x/%x\n", | ||
2094 | cmd, did, irsp->ulpStatus, | ||
2095 | irsp->un.ulpWord[4]); | ||
2096 | } | ||
2097 | else { | ||
2098 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | ||
2010 | "0108 No retry ELS command x%x to remote " | 2099 | "0108 No retry ELS command x%x to remote " |
2011 | "NPORT x%x Retried:%d Error:x%x/%x\n", | 2100 | "NPORT x%x Retried:%d Error:x%x/%x\n", |
2012 | cmd, did, cmdiocb->retry, irsp->ulpStatus, | 2101 | cmd, did, cmdiocb->retry, irsp->ulpStatus, |
2013 | irsp->un.ulpWord[4]); | 2102 | irsp->un.ulpWord[4]); |
2103 | } | ||
2104 | return 0; | ||
2105 | } | ||
2106 | |||
2107 | static int | ||
2108 | lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1) | ||
2109 | { | ||
2110 | struct lpfc_dmabuf *buf_ptr; | ||
2111 | |||
2112 | /* Free the response before processing the command. */ | ||
2113 | if (!list_empty(&buf_ptr1->list)) { | ||
2114 | list_remove_head(&buf_ptr1->list, buf_ptr, | ||
2115 | struct lpfc_dmabuf, | ||
2116 | list); | ||
2117 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | ||
2118 | kfree(buf_ptr); | ||
2119 | } | ||
2120 | lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys); | ||
2121 | kfree(buf_ptr1); | ||
2122 | return 0; | ||
2123 | } | ||
2124 | |||
2125 | static int | ||
2126 | lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr) | ||
2127 | { | ||
2128 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | ||
2129 | kfree(buf_ptr); | ||
2014 | return 0; | 2130 | return 0; |
2015 | } | 2131 | } |
2016 | 2132 | ||
@@ -2018,30 +2134,63 @@ int | |||
2018 | lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) | 2134 | lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) |
2019 | { | 2135 | { |
2020 | struct lpfc_dmabuf *buf_ptr, *buf_ptr1; | 2136 | struct lpfc_dmabuf *buf_ptr, *buf_ptr1; |
2137 | struct lpfc_nodelist *ndlp; | ||
2021 | 2138 | ||
2022 | if (elsiocb->context1) { | 2139 | ndlp = (struct lpfc_nodelist *)elsiocb->context1; |
2023 | lpfc_nlp_put(elsiocb->context1); | 2140 | if (ndlp) { |
2141 | if (ndlp->nlp_flag & NLP_DEFER_RM) { | ||
2142 | lpfc_nlp_put(ndlp); | ||
2143 | |||
2144 | /* If the ndlp is not being used by another discovery | ||
2145 | * thread, free it. | ||
2146 | */ | ||
2147 | if (!lpfc_nlp_not_used(ndlp)) { | ||
2148 | /* If ndlp is being used by another discovery | ||
2149 | * thread, just clear NLP_DEFER_RM | ||
2150 | */ | ||
2151 | ndlp->nlp_flag &= ~NLP_DEFER_RM; | ||
2152 | } | ||
2153 | } | ||
2154 | else | ||
2155 | lpfc_nlp_put(ndlp); | ||
2024 | elsiocb->context1 = NULL; | 2156 | elsiocb->context1 = NULL; |
2025 | } | 2157 | } |
2026 | /* context2 = cmd, context2->next = rsp, context3 = bpl */ | 2158 | /* context2 = cmd, context2->next = rsp, context3 = bpl */ |
2027 | if (elsiocb->context2) { | 2159 | if (elsiocb->context2) { |
2028 | buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2; | 2160 | if (elsiocb->iocb_flag & LPFC_DELAY_MEM_FREE) { |
2029 | /* Free the response before processing the command. */ | 2161 | /* Firmware could still be in progress of DMAing |
2030 | if (!list_empty(&buf_ptr1->list)) { | 2162 | * payload, so don't free data buffer till after |
2031 | list_remove_head(&buf_ptr1->list, buf_ptr, | 2163 | * a hbeat. |
2032 | struct lpfc_dmabuf, | 2164 | */ |
2033 | list); | 2165 | elsiocb->iocb_flag &= ~LPFC_DELAY_MEM_FREE; |
2034 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | 2166 | buf_ptr = elsiocb->context2; |
2035 | kfree(buf_ptr); | 2167 | elsiocb->context2 = NULL; |
2168 | if (buf_ptr) { | ||
2169 | buf_ptr1 = NULL; | ||
2170 | spin_lock_irq(&phba->hbalock); | ||
2171 | if (!list_empty(&buf_ptr->list)) { | ||
2172 | list_remove_head(&buf_ptr->list, | ||
2173 | buf_ptr1, struct lpfc_dmabuf, | ||
2174 | list); | ||
2175 | INIT_LIST_HEAD(&buf_ptr1->list); | ||
2176 | list_add_tail(&buf_ptr1->list, | ||
2177 | &phba->elsbuf); | ||
2178 | phba->elsbuf_cnt++; | ||
2179 | } | ||
2180 | INIT_LIST_HEAD(&buf_ptr->list); | ||
2181 | list_add_tail(&buf_ptr->list, &phba->elsbuf); | ||
2182 | phba->elsbuf_cnt++; | ||
2183 | spin_unlock_irq(&phba->hbalock); | ||
2184 | } | ||
2185 | } else { | ||
2186 | buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2; | ||
2187 | lpfc_els_free_data(phba, buf_ptr1); | ||
2036 | } | 2188 | } |
2037 | lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys); | ||
2038 | kfree(buf_ptr1); | ||
2039 | } | 2189 | } |
2040 | 2190 | ||
2041 | if (elsiocb->context3) { | 2191 | if (elsiocb->context3) { |
2042 | buf_ptr = (struct lpfc_dmabuf *) elsiocb->context3; | 2192 | buf_ptr = (struct lpfc_dmabuf *) elsiocb->context3; |
2043 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | 2193 | lpfc_els_free_bpl(phba, buf_ptr); |
2044 | kfree(buf_ptr); | ||
2045 | } | 2194 | } |
2046 | lpfc_sli_release_iocbq(phba, elsiocb); | 2195 | lpfc_sli_release_iocbq(phba, elsiocb); |
2047 | return 0; | 2196 | return 0; |
@@ -2065,15 +2214,20 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2065 | "Data: x%x x%x x%x\n", | 2214 | "Data: x%x x%x x%x\n", |
2066 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, | 2215 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, |
2067 | ndlp->nlp_rpi); | 2216 | ndlp->nlp_rpi); |
2068 | switch (ndlp->nlp_state) { | 2217 | |
2069 | case NLP_STE_UNUSED_NODE: /* node is just allocated */ | 2218 | if (ndlp->nlp_state == NLP_STE_NPR_NODE) { |
2070 | lpfc_drop_node(vport, ndlp); | 2219 | /* NPort Recovery mode or node is just allocated */ |
2071 | break; | 2220 | if (!lpfc_nlp_not_used(ndlp)) { |
2072 | case NLP_STE_NPR_NODE: /* NPort Recovery mode */ | 2221 | /* If the ndlp is being used by another discovery |
2073 | lpfc_unreg_rpi(vport, ndlp); | 2222 | * thread, just unregister the RPI. |
2074 | break; | 2223 | */ |
2075 | default: | 2224 | lpfc_unreg_rpi(vport, ndlp); |
2076 | break; | 2225 | } else { |
2226 | /* Indicate the node has already released, should | ||
2227 | * not reference to it from within lpfc_els_free_iocb. | ||
2228 | */ | ||
2229 | cmdiocb->context1 = NULL; | ||
2230 | } | ||
2077 | } | 2231 | } |
2078 | lpfc_els_free_iocb(phba, cmdiocb); | 2232 | lpfc_els_free_iocb(phba, cmdiocb); |
2079 | return; | 2233 | return; |
@@ -2089,7 +2243,14 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2089 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 2243 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
2090 | kfree(mp); | 2244 | kfree(mp); |
2091 | mempool_free(pmb, phba->mbox_mem_pool); | 2245 | mempool_free(pmb, phba->mbox_mem_pool); |
2092 | lpfc_nlp_put(ndlp); | 2246 | if (ndlp) { |
2247 | lpfc_nlp_put(ndlp); | ||
2248 | /* This is the end of the default RPI cleanup logic for this | ||
2249 | * ndlp. If no other discovery threads are using this ndlp. | ||
2250 | * we should free all resources associated with it. | ||
2251 | */ | ||
2252 | lpfc_nlp_not_used(ndlp); | ||
2253 | } | ||
2093 | return; | 2254 | return; |
2094 | } | 2255 | } |
2095 | 2256 | ||
@@ -2100,15 +2261,29 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2100 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 2261 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
2101 | struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL; | 2262 | struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL; |
2102 | struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL; | 2263 | struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL; |
2103 | IOCB_t *irsp; | 2264 | IOCB_t *irsp; |
2265 | uint8_t *pcmd; | ||
2104 | LPFC_MBOXQ_t *mbox = NULL; | 2266 | LPFC_MBOXQ_t *mbox = NULL; |
2105 | struct lpfc_dmabuf *mp = NULL; | 2267 | struct lpfc_dmabuf *mp = NULL; |
2268 | uint32_t ls_rjt = 0; | ||
2106 | 2269 | ||
2107 | irsp = &rspiocb->iocb; | 2270 | irsp = &rspiocb->iocb; |
2108 | 2271 | ||
2109 | if (cmdiocb->context_un.mbox) | 2272 | if (cmdiocb->context_un.mbox) |
2110 | mbox = cmdiocb->context_un.mbox; | 2273 | mbox = cmdiocb->context_un.mbox; |
2111 | 2274 | ||
2275 | /* First determine if this is a LS_RJT cmpl. Note, this callback | ||
2276 | * function can have cmdiocb->contest1 (ndlp) field set to NULL. | ||
2277 | */ | ||
2278 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); | ||
2279 | if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { | ||
2280 | /* A LS_RJT associated with Default RPI cleanup has its own | ||
2281 | * seperate code path. | ||
2282 | */ | ||
2283 | if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI)) | ||
2284 | ls_rjt = 1; | ||
2285 | } | ||
2286 | |||
2112 | /* Check to see if link went down during discovery */ | 2287 | /* Check to see if link went down during discovery */ |
2113 | if (!ndlp || lpfc_els_chk_latt(vport)) { | 2288 | if (!ndlp || lpfc_els_chk_latt(vport)) { |
2114 | if (mbox) { | 2289 | if (mbox) { |
@@ -2119,6 +2294,15 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2119 | } | 2294 | } |
2120 | mempool_free(mbox, phba->mbox_mem_pool); | 2295 | mempool_free(mbox, phba->mbox_mem_pool); |
2121 | } | 2296 | } |
2297 | if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) | ||
2298 | if (lpfc_nlp_not_used(ndlp)) { | ||
2299 | ndlp = NULL; | ||
2300 | /* Indicate the node has already released, | ||
2301 | * should not reference to it from within | ||
2302 | * the routine lpfc_els_free_iocb. | ||
2303 | */ | ||
2304 | cmdiocb->context1 = NULL; | ||
2305 | } | ||
2122 | goto out; | 2306 | goto out; |
2123 | } | 2307 | } |
2124 | 2308 | ||
@@ -2150,20 +2334,39 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2150 | lpfc_nlp_set_state(vport, ndlp, | 2334 | lpfc_nlp_set_state(vport, ndlp, |
2151 | NLP_STE_REG_LOGIN_ISSUE); | 2335 | NLP_STE_REG_LOGIN_ISSUE); |
2152 | } | 2336 | } |
2153 | if (lpfc_sli_issue_mbox(phba, mbox, | 2337 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) |
2154 | (MBX_NOWAIT | MBX_STOP_IOCB)) | ||
2155 | != MBX_NOT_FINISHED) { | 2338 | != MBX_NOT_FINISHED) { |
2156 | goto out; | 2339 | goto out; |
2157 | } | 2340 | } |
2158 | lpfc_nlp_put(ndlp); | 2341 | |
2159 | /* NOTE: we should have messages for unsuccessful | 2342 | /* ELS rsp: Cannot issue reg_login for <NPortid> */ |
2160 | reglogin */ | 2343 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
2344 | "0138 ELS rsp: Cannot issue reg_login for x%x " | ||
2345 | "Data: x%x x%x x%x\n", | ||
2346 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, | ||
2347 | ndlp->nlp_rpi); | ||
2348 | |||
2349 | if (lpfc_nlp_not_used(ndlp)) { | ||
2350 | ndlp = NULL; | ||
2351 | /* Indicate node has already been released, | ||
2352 | * should not reference to it from within | ||
2353 | * the routine lpfc_els_free_iocb. | ||
2354 | */ | ||
2355 | cmdiocb->context1 = NULL; | ||
2356 | } | ||
2161 | } else { | 2357 | } else { |
2162 | /* Do not drop node for lpfc_els_abort'ed ELS cmds */ | 2358 | /* Do not drop node for lpfc_els_abort'ed ELS cmds */ |
2163 | if (!lpfc_error_lost_link(irsp) && | 2359 | if (!lpfc_error_lost_link(irsp) && |
2164 | ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | 2360 | ndlp->nlp_flag & NLP_ACC_REGLOGIN) { |
2165 | lpfc_drop_node(vport, ndlp); | 2361 | if (lpfc_nlp_not_used(ndlp)) { |
2166 | ndlp = NULL; | 2362 | ndlp = NULL; |
2363 | /* Indicate node has already been | ||
2364 | * released, should not reference | ||
2365 | * to it from within the routine | ||
2366 | * lpfc_els_free_iocb. | ||
2367 | */ | ||
2368 | cmdiocb->context1 = NULL; | ||
2369 | } | ||
2167 | } | 2370 | } |
2168 | } | 2371 | } |
2169 | mp = (struct lpfc_dmabuf *) mbox->context1; | 2372 | mp = (struct lpfc_dmabuf *) mbox->context1; |
@@ -2178,7 +2381,21 @@ out: | |||
2178 | spin_lock_irq(shost->host_lock); | 2381 | spin_lock_irq(shost->host_lock); |
2179 | ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); | 2382 | ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); |
2180 | spin_unlock_irq(shost->host_lock); | 2383 | spin_unlock_irq(shost->host_lock); |
2384 | |||
2385 | /* If the node is not being used by another discovery thread, | ||
2386 | * and we are sending a reject, we are done with it. | ||
2387 | * Release driver reference count here and free associated | ||
2388 | * resources. | ||
2389 | */ | ||
2390 | if (ls_rjt) | ||
2391 | if (lpfc_nlp_not_used(ndlp)) | ||
2392 | /* Indicate node has already been released, | ||
2393 | * should not reference to it from within | ||
2394 | * the routine lpfc_els_free_iocb. | ||
2395 | */ | ||
2396 | cmdiocb->context1 = NULL; | ||
2181 | } | 2397 | } |
2398 | |||
2182 | lpfc_els_free_iocb(phba, cmdiocb); | 2399 | lpfc_els_free_iocb(phba, cmdiocb); |
2183 | return; | 2400 | return; |
2184 | } | 2401 | } |
@@ -2349,14 +2566,6 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, | |||
2349 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; | 2566 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
2350 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 2567 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
2351 | 2568 | ||
2352 | /* If the node is in the UNUSED state, and we are sending | ||
2353 | * a reject, we are done with it. Release driver reference | ||
2354 | * count here. The outstanding els will release its reference on | ||
2355 | * completion and the node can be freed then. | ||
2356 | */ | ||
2357 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | ||
2358 | lpfc_nlp_put(ndlp); | ||
2359 | |||
2360 | if (rc == IOCB_ERROR) { | 2569 | if (rc == IOCB_ERROR) { |
2361 | lpfc_els_free_iocb(phba, elsiocb); | 2570 | lpfc_els_free_iocb(phba, elsiocb); |
2362 | return 1; | 2571 | return 1; |
@@ -2642,7 +2851,10 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport) | |||
2642 | } | 2851 | } |
2643 | } | 2852 | } |
2644 | } | 2853 | } |
2645 | if (sentplogi == 0) { | 2854 | if (sentplogi) { |
2855 | lpfc_set_disctmo(vport); | ||
2856 | } | ||
2857 | else { | ||
2646 | spin_lock_irq(shost->host_lock); | 2858 | spin_lock_irq(shost->host_lock); |
2647 | vport->fc_flag &= ~FC_NLP_MORE; | 2859 | vport->fc_flag &= ~FC_NLP_MORE; |
2648 | spin_unlock_irq(shost->host_lock); | 2860 | spin_unlock_irq(shost->host_lock); |
@@ -2830,10 +3042,10 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2830 | "RCV RSCN defer: did:x%x/ste:x%x flg:x%x", | 3042 | "RCV RSCN defer: did:x%x/ste:x%x flg:x%x", |
2831 | ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); | 3043 | ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); |
2832 | 3044 | ||
3045 | spin_lock_irq(shost->host_lock); | ||
2833 | vport->fc_flag |= FC_RSCN_DEFERRED; | 3046 | vport->fc_flag |= FC_RSCN_DEFERRED; |
2834 | if ((rscn_cnt < FC_MAX_HOLD_RSCN) && | 3047 | if ((rscn_cnt < FC_MAX_HOLD_RSCN) && |
2835 | !(vport->fc_flag & FC_RSCN_DISCOVERY)) { | 3048 | !(vport->fc_flag & FC_RSCN_DISCOVERY)) { |
2836 | spin_lock_irq(shost->host_lock); | ||
2837 | vport->fc_flag |= FC_RSCN_MODE; | 3049 | vport->fc_flag |= FC_RSCN_MODE; |
2838 | spin_unlock_irq(shost->host_lock); | 3050 | spin_unlock_irq(shost->host_lock); |
2839 | if (rscn_cnt) { | 3051 | if (rscn_cnt) { |
@@ -2862,7 +3074,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2862 | vport->fc_rscn_id_cnt, vport->fc_flag, | 3074 | vport->fc_rscn_id_cnt, vport->fc_flag, |
2863 | vport->port_state); | 3075 | vport->port_state); |
2864 | } else { | 3076 | } else { |
2865 | spin_lock_irq(shost->host_lock); | ||
2866 | vport->fc_flag |= FC_RSCN_DISCOVERY; | 3077 | vport->fc_flag |= FC_RSCN_DISCOVERY; |
2867 | spin_unlock_irq(shost->host_lock); | 3078 | spin_unlock_irq(shost->host_lock); |
2868 | /* ReDiscovery RSCN */ | 3079 | /* ReDiscovery RSCN */ |
@@ -2877,7 +3088,9 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2877 | 3088 | ||
2878 | /* send RECOVERY event for ALL nodes that match RSCN payload */ | 3089 | /* send RECOVERY event for ALL nodes that match RSCN payload */ |
2879 | lpfc_rscn_recovery_check(vport); | 3090 | lpfc_rscn_recovery_check(vport); |
3091 | spin_lock_irq(shost->host_lock); | ||
2880 | vport->fc_flag &= ~FC_RSCN_DEFERRED; | 3092 | vport->fc_flag &= ~FC_RSCN_DEFERRED; |
3093 | spin_unlock_irq(shost->host_lock); | ||
2881 | return 0; | 3094 | return 0; |
2882 | } | 3095 | } |
2883 | 3096 | ||
@@ -2929,6 +3142,8 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport) | |||
2929 | 3142 | ||
2930 | /* To process RSCN, first compare RSCN data with NameServer */ | 3143 | /* To process RSCN, first compare RSCN data with NameServer */ |
2931 | vport->fc_ns_retry = 0; | 3144 | vport->fc_ns_retry = 0; |
3145 | vport->num_disc_nodes = 0; | ||
3146 | |||
2932 | ndlp = lpfc_findnode_did(vport, NameServer_DID); | 3147 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
2933 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 3148 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { |
2934 | /* Good ndlp, issue CT Request to NameServer */ | 3149 | /* Good ndlp, issue CT Request to NameServer */ |
@@ -3022,8 +3237,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3022 | mbox->mb.un.varInitLnk.lipsr_AL_PA = 0; | 3237 | mbox->mb.un.varInitLnk.lipsr_AL_PA = 0; |
3023 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 3238 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
3024 | mbox->vport = vport; | 3239 | mbox->vport = vport; |
3025 | rc = lpfc_sli_issue_mbox | 3240 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
3026 | (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); | ||
3027 | lpfc_set_loopback_flag(phba); | 3241 | lpfc_set_loopback_flag(phba); |
3028 | if (rc == MBX_NOT_FINISHED) { | 3242 | if (rc == MBX_NOT_FINISHED) { |
3029 | mempool_free(mbox, phba->mbox_mem_pool); | 3243 | mempool_free(mbox, phba->mbox_mem_pool); |
@@ -3140,7 +3354,10 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3140 | elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize, | 3354 | elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize, |
3141 | lpfc_max_els_tries, ndlp, | 3355 | lpfc_max_els_tries, ndlp, |
3142 | ndlp->nlp_DID, ELS_CMD_ACC); | 3356 | ndlp->nlp_DID, ELS_CMD_ACC); |
3357 | |||
3358 | /* Decrement the ndlp reference count from previous mbox command */ | ||
3143 | lpfc_nlp_put(ndlp); | 3359 | lpfc_nlp_put(ndlp); |
3360 | |||
3144 | if (!elsiocb) | 3361 | if (!elsiocb) |
3145 | return; | 3362 | return; |
3146 | 3363 | ||
@@ -3160,13 +3377,13 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3160 | status |= 0x4; | 3377 | status |= 0x4; |
3161 | 3378 | ||
3162 | rps_rsp->rsvd1 = 0; | 3379 | rps_rsp->rsvd1 = 0; |
3163 | rps_rsp->portStatus = be16_to_cpu(status); | 3380 | rps_rsp->portStatus = cpu_to_be16(status); |
3164 | rps_rsp->linkFailureCnt = be32_to_cpu(mb->un.varRdLnk.linkFailureCnt); | 3381 | rps_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt); |
3165 | rps_rsp->lossSyncCnt = be32_to_cpu(mb->un.varRdLnk.lossSyncCnt); | 3382 | rps_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt); |
3166 | rps_rsp->lossSignalCnt = be32_to_cpu(mb->un.varRdLnk.lossSignalCnt); | 3383 | rps_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt); |
3167 | rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt); | 3384 | rps_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt); |
3168 | rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord); | 3385 | rps_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord); |
3169 | rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt); | 3386 | rps_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt); |
3170 | /* Xmit ELS RPS ACC response tag <ulpIoTag> */ | 3387 | /* Xmit ELS RPS ACC response tag <ulpIoTag> */ |
3171 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS, | 3388 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS, |
3172 | "0118 Xmit ELS RPS ACC response tag x%x xri x%x, " | 3389 | "0118 Xmit ELS RPS ACC response tag x%x xri x%x, " |
@@ -3223,11 +3440,13 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3223 | mbox->context2 = lpfc_nlp_get(ndlp); | 3440 | mbox->context2 = lpfc_nlp_get(ndlp); |
3224 | mbox->vport = vport; | 3441 | mbox->vport = vport; |
3225 | mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; | 3442 | mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; |
3226 | if (lpfc_sli_issue_mbox (phba, mbox, | 3443 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) |
3227 | (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) | 3444 | != MBX_NOT_FINISHED) |
3228 | /* Mbox completion will send ELS Response */ | 3445 | /* Mbox completion will send ELS Response */ |
3229 | return 0; | 3446 | return 0; |
3230 | 3447 | /* Decrement reference count used for the failed mbox | |
3448 | * command. | ||
3449 | */ | ||
3231 | lpfc_nlp_put(ndlp); | 3450 | lpfc_nlp_put(ndlp); |
3232 | mempool_free(mbox, phba->mbox_mem_pool); | 3451 | mempool_free(mbox, phba->mbox_mem_pool); |
3233 | } | 3452 | } |
@@ -3461,6 +3680,7 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3461 | * other NLP_FABRIC logins | 3680 | * other NLP_FABRIC logins |
3462 | */ | 3681 | */ |
3463 | lpfc_drop_node(vport, ndlp); | 3682 | lpfc_drop_node(vport, ndlp); |
3683 | |||
3464 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 3684 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { |
3465 | /* Fail outstanding I/O now since this | 3685 | /* Fail outstanding I/O now since this |
3466 | * device is marked for PLOGI | 3686 | * device is marked for PLOGI |
@@ -3469,8 +3689,6 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3469 | } | 3689 | } |
3470 | } | 3690 | } |
3471 | 3691 | ||
3472 | vport->port_state = LPFC_FLOGI; | ||
3473 | lpfc_set_disctmo(vport); | ||
3474 | lpfc_initial_flogi(vport); | 3692 | lpfc_initial_flogi(vport); |
3475 | return 0; | 3693 | return 0; |
3476 | } | 3694 | } |
@@ -3711,6 +3929,7 @@ static void | |||
3711 | lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 3929 | lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
3712 | struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb) | 3930 | struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb) |
3713 | { | 3931 | { |
3932 | struct Scsi_Host *shost; | ||
3714 | struct lpfc_nodelist *ndlp; | 3933 | struct lpfc_nodelist *ndlp; |
3715 | struct ls_rjt stat; | 3934 | struct ls_rjt stat; |
3716 | uint32_t *payload; | 3935 | uint32_t *payload; |
@@ -3750,11 +3969,19 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3750 | goto dropit; | 3969 | goto dropit; |
3751 | 3970 | ||
3752 | lpfc_nlp_init(vport, ndlp, did); | 3971 | lpfc_nlp_init(vport, ndlp, did); |
3972 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | ||
3753 | newnode = 1; | 3973 | newnode = 1; |
3754 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { | 3974 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { |
3755 | ndlp->nlp_type |= NLP_FABRIC; | 3975 | ndlp->nlp_type |= NLP_FABRIC; |
3756 | } | 3976 | } |
3757 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); | 3977 | } |
3978 | else { | ||
3979 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { | ||
3980 | /* This is simular to the new node path */ | ||
3981 | lpfc_nlp_get(ndlp); | ||
3982 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | ||
3983 | newnode = 1; | ||
3984 | } | ||
3758 | } | 3985 | } |
3759 | 3986 | ||
3760 | phba->fc_stat.elsRcvFrame++; | 3987 | phba->fc_stat.elsRcvFrame++; |
@@ -3783,6 +4010,12 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3783 | rjt_err = LSRJT_UNABLE_TPC; | 4010 | rjt_err = LSRJT_UNABLE_TPC; |
3784 | break; | 4011 | break; |
3785 | } | 4012 | } |
4013 | |||
4014 | shost = lpfc_shost_from_vport(vport); | ||
4015 | spin_lock_irq(shost->host_lock); | ||
4016 | ndlp->nlp_flag &= ~NLP_TARGET_REMOVE; | ||
4017 | spin_unlock_irq(shost->host_lock); | ||
4018 | |||
3786 | lpfc_disc_state_machine(vport, ndlp, elsiocb, | 4019 | lpfc_disc_state_machine(vport, ndlp, elsiocb, |
3787 | NLP_EVT_RCV_PLOGI); | 4020 | NLP_EVT_RCV_PLOGI); |
3788 | 4021 | ||
@@ -3795,7 +4028,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3795 | phba->fc_stat.elsRcvFLOGI++; | 4028 | phba->fc_stat.elsRcvFLOGI++; |
3796 | lpfc_els_rcv_flogi(vport, elsiocb, ndlp); | 4029 | lpfc_els_rcv_flogi(vport, elsiocb, ndlp); |
3797 | if (newnode) | 4030 | if (newnode) |
3798 | lpfc_drop_node(vport, ndlp); | 4031 | lpfc_nlp_put(ndlp); |
3799 | break; | 4032 | break; |
3800 | case ELS_CMD_LOGO: | 4033 | case ELS_CMD_LOGO: |
3801 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 4034 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3825,7 +4058,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3825 | phba->fc_stat.elsRcvRSCN++; | 4058 | phba->fc_stat.elsRcvRSCN++; |
3826 | lpfc_els_rcv_rscn(vport, elsiocb, ndlp); | 4059 | lpfc_els_rcv_rscn(vport, elsiocb, ndlp); |
3827 | if (newnode) | 4060 | if (newnode) |
3828 | lpfc_drop_node(vport, ndlp); | 4061 | lpfc_nlp_put(ndlp); |
3829 | break; | 4062 | break; |
3830 | case ELS_CMD_ADISC: | 4063 | case ELS_CMD_ADISC: |
3831 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 4064 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3897,7 +4130,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3897 | phba->fc_stat.elsRcvLIRR++; | 4130 | phba->fc_stat.elsRcvLIRR++; |
3898 | lpfc_els_rcv_lirr(vport, elsiocb, ndlp); | 4131 | lpfc_els_rcv_lirr(vport, elsiocb, ndlp); |
3899 | if (newnode) | 4132 | if (newnode) |
3900 | lpfc_drop_node(vport, ndlp); | 4133 | lpfc_nlp_put(ndlp); |
3901 | break; | 4134 | break; |
3902 | case ELS_CMD_RPS: | 4135 | case ELS_CMD_RPS: |
3903 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 4136 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3907,7 +4140,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3907 | phba->fc_stat.elsRcvRPS++; | 4140 | phba->fc_stat.elsRcvRPS++; |
3908 | lpfc_els_rcv_rps(vport, elsiocb, ndlp); | 4141 | lpfc_els_rcv_rps(vport, elsiocb, ndlp); |
3909 | if (newnode) | 4142 | if (newnode) |
3910 | lpfc_drop_node(vport, ndlp); | 4143 | lpfc_nlp_put(ndlp); |
3911 | break; | 4144 | break; |
3912 | case ELS_CMD_RPL: | 4145 | case ELS_CMD_RPL: |
3913 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 4146 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3917,7 +4150,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3917 | phba->fc_stat.elsRcvRPL++; | 4150 | phba->fc_stat.elsRcvRPL++; |
3918 | lpfc_els_rcv_rpl(vport, elsiocb, ndlp); | 4151 | lpfc_els_rcv_rpl(vport, elsiocb, ndlp); |
3919 | if (newnode) | 4152 | if (newnode) |
3920 | lpfc_drop_node(vport, ndlp); | 4153 | lpfc_nlp_put(ndlp); |
3921 | break; | 4154 | break; |
3922 | case ELS_CMD_RNID: | 4155 | case ELS_CMD_RNID: |
3923 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 4156 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3927,7 +4160,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3927 | phba->fc_stat.elsRcvRNID++; | 4160 | phba->fc_stat.elsRcvRNID++; |
3928 | lpfc_els_rcv_rnid(vport, elsiocb, ndlp); | 4161 | lpfc_els_rcv_rnid(vport, elsiocb, ndlp); |
3929 | if (newnode) | 4162 | if (newnode) |
3930 | lpfc_drop_node(vport, ndlp); | 4163 | lpfc_nlp_put(ndlp); |
3931 | break; | 4164 | break; |
3932 | default: | 4165 | default: |
3933 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 4166 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
@@ -3942,7 +4175,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3942 | "0115 Unknown ELS command x%x " | 4175 | "0115 Unknown ELS command x%x " |
3943 | "received from NPORT x%x\n", cmd, did); | 4176 | "received from NPORT x%x\n", cmd, did); |
3944 | if (newnode) | 4177 | if (newnode) |
3945 | lpfc_drop_node(vport, ndlp); | 4178 | lpfc_nlp_put(ndlp); |
3946 | break; | 4179 | break; |
3947 | } | 4180 | } |
3948 | 4181 | ||
@@ -3958,10 +4191,11 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3958 | return; | 4191 | return; |
3959 | 4192 | ||
3960 | dropit: | 4193 | dropit: |
3961 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | 4194 | if (vport && !(vport->load_flag & FC_UNLOADING)) |
4195 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | ||
3962 | "(%d):0111 Dropping received ELS cmd " | 4196 | "(%d):0111 Dropping received ELS cmd " |
3963 | "Data: x%x x%x x%x\n", | 4197 | "Data: x%x x%x x%x\n", |
3964 | vport ? vport->vpi : 0xffff, icmd->ulpStatus, | 4198 | vport->vpi, icmd->ulpStatus, |
3965 | icmd->un.ulpWord[4], icmd->ulpTimeout); | 4199 | icmd->un.ulpWord[4], icmd->ulpTimeout); |
3966 | phba->fc_stat.elsRcvDrop++; | 4200 | phba->fc_stat.elsRcvDrop++; |
3967 | } | 4201 | } |
@@ -4114,8 +4348,9 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4114 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; | 4348 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
4115 | MAILBOX_t *mb = &pmb->mb; | 4349 | MAILBOX_t *mb = &pmb->mb; |
4116 | 4350 | ||
4351 | spin_lock_irq(shost->host_lock); | ||
4117 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | 4352 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; |
4118 | lpfc_nlp_put(ndlp); | 4353 | spin_unlock_irq(shost->host_lock); |
4119 | 4354 | ||
4120 | if (mb->mbxStatus) { | 4355 | if (mb->mbxStatus) { |
4121 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 4356 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
@@ -4135,7 +4370,9 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4135 | default: | 4370 | default: |
4136 | /* Try to recover from this error */ | 4371 | /* Try to recover from this error */ |
4137 | lpfc_mbx_unreg_vpi(vport); | 4372 | lpfc_mbx_unreg_vpi(vport); |
4373 | spin_lock_irq(shost->host_lock); | ||
4138 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 4374 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
4375 | spin_unlock_irq(shost->host_lock); | ||
4139 | lpfc_initial_fdisc(vport); | 4376 | lpfc_initial_fdisc(vport); |
4140 | break; | 4377 | break; |
4141 | } | 4378 | } |
@@ -4146,14 +4383,21 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4146 | else | 4383 | else |
4147 | lpfc_do_scr_ns_plogi(phba, vport); | 4384 | lpfc_do_scr_ns_plogi(phba, vport); |
4148 | } | 4385 | } |
4386 | |||
4387 | /* Now, we decrement the ndlp reference count held for this | ||
4388 | * callback function | ||
4389 | */ | ||
4390 | lpfc_nlp_put(ndlp); | ||
4391 | |||
4149 | mempool_free(pmb, phba->mbox_mem_pool); | 4392 | mempool_free(pmb, phba->mbox_mem_pool); |
4150 | return; | 4393 | return; |
4151 | } | 4394 | } |
4152 | 4395 | ||
4153 | void | 4396 | static void |
4154 | lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, | 4397 | lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, |
4155 | struct lpfc_nodelist *ndlp) | 4398 | struct lpfc_nodelist *ndlp) |
4156 | { | 4399 | { |
4400 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
4157 | LPFC_MBOXQ_t *mbox; | 4401 | LPFC_MBOXQ_t *mbox; |
4158 | 4402 | ||
4159 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4403 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
@@ -4162,25 +4406,31 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, | |||
4162 | mbox->vport = vport; | 4406 | mbox->vport = vport; |
4163 | mbox->context2 = lpfc_nlp_get(ndlp); | 4407 | mbox->context2 = lpfc_nlp_get(ndlp); |
4164 | mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport; | 4408 | mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport; |
4165 | if (lpfc_sli_issue_mbox(phba, mbox, | 4409 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) |
4166 | MBX_NOWAIT | MBX_STOP_IOCB) | ||
4167 | == MBX_NOT_FINISHED) { | 4410 | == MBX_NOT_FINISHED) { |
4411 | /* mailbox command not success, decrement ndlp | ||
4412 | * reference count for this command | ||
4413 | */ | ||
4414 | lpfc_nlp_put(ndlp); | ||
4168 | mempool_free(mbox, phba->mbox_mem_pool); | 4415 | mempool_free(mbox, phba->mbox_mem_pool); |
4169 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | ||
4170 | 4416 | ||
4171 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
4172 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 4417 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
4173 | "0253 Register VPI: Can't send mbox\n"); | 4418 | "0253 Register VPI: Can't send mbox\n"); |
4419 | goto mbox_err_exit; | ||
4174 | } | 4420 | } |
4175 | } else { | 4421 | } else { |
4176 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
4177 | |||
4178 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 4422 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
4179 | "0254 Register VPI: no memory\n"); | 4423 | "0254 Register VPI: no memory\n"); |
4180 | 4424 | goto mbox_err_exit; | |
4181 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | ||
4182 | lpfc_nlp_put(ndlp); | ||
4183 | } | 4425 | } |
4426 | return; | ||
4427 | |||
4428 | mbox_err_exit: | ||
4429 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
4430 | spin_lock_irq(shost->host_lock); | ||
4431 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | ||
4432 | spin_unlock_irq(shost->host_lock); | ||
4433 | return; | ||
4184 | } | 4434 | } |
4185 | 4435 | ||
4186 | static void | 4436 | static void |
@@ -4251,7 +4501,9 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4251 | lpfc_unreg_rpi(vport, np); | 4501 | lpfc_unreg_rpi(vport, np); |
4252 | } | 4502 | } |
4253 | lpfc_mbx_unreg_vpi(vport); | 4503 | lpfc_mbx_unreg_vpi(vport); |
4504 | spin_lock_irq(shost->host_lock); | ||
4254 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 4505 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
4506 | spin_unlock_irq(shost->host_lock); | ||
4255 | } | 4507 | } |
4256 | 4508 | ||
4257 | if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) | 4509 | if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) |
@@ -4259,14 +4511,15 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4259 | else | 4511 | else |
4260 | lpfc_do_scr_ns_plogi(phba, vport); | 4512 | lpfc_do_scr_ns_plogi(phba, vport); |
4261 | 4513 | ||
4262 | lpfc_nlp_put(ndlp); /* Free Fabric ndlp for vports */ | 4514 | /* Unconditionaly kick off releasing fabric node for vports */ |
4515 | lpfc_nlp_put(ndlp); | ||
4263 | } | 4516 | } |
4264 | 4517 | ||
4265 | out: | 4518 | out: |
4266 | lpfc_els_free_iocb(phba, cmdiocb); | 4519 | lpfc_els_free_iocb(phba, cmdiocb); |
4267 | } | 4520 | } |
4268 | 4521 | ||
4269 | int | 4522 | static int |
4270 | lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 4523 | lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
4271 | uint8_t retry) | 4524 | uint8_t retry) |
4272 | { | 4525 | { |
@@ -4539,7 +4792,7 @@ lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4539 | } | 4792 | } |
4540 | } | 4793 | } |
4541 | 4794 | ||
4542 | int | 4795 | static int |
4543 | lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) | 4796 | lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) |
4544 | { | 4797 | { |
4545 | unsigned long iflags; | 4798 | unsigned long iflags; |
@@ -4583,7 +4836,7 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) | |||
4583 | } | 4836 | } |
4584 | 4837 | ||
4585 | 4838 | ||
4586 | void lpfc_fabric_abort_vport(struct lpfc_vport *vport) | 4839 | static void lpfc_fabric_abort_vport(struct lpfc_vport *vport) |
4587 | { | 4840 | { |
4588 | LIST_HEAD(completions); | 4841 | LIST_HEAD(completions); |
4589 | struct lpfc_hba *phba = vport->phba; | 4842 | struct lpfc_hba *phba = vport->phba; |
@@ -4663,6 +4916,7 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba) | |||
4663 | } | 4916 | } |
4664 | 4917 | ||
4665 | 4918 | ||
4919 | #if 0 | ||
4666 | void lpfc_fabric_abort_flogi(struct lpfc_hba *phba) | 4920 | void lpfc_fabric_abort_flogi(struct lpfc_hba *phba) |
4667 | { | 4921 | { |
4668 | LIST_HEAD(completions); | 4922 | LIST_HEAD(completions); |
@@ -4693,5 +4947,6 @@ void lpfc_fabric_abort_flogi(struct lpfc_hba *phba) | |||
4693 | (piocb->iocb_cmpl) (phba, piocb, piocb); | 4947 | (piocb->iocb_cmpl) (phba, piocb, piocb); |
4694 | } | 4948 | } |
4695 | } | 4949 | } |
4950 | #endif /* 0 */ | ||
4696 | 4951 | ||
4697 | 4952 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index c81c2b3228d6..dc042bd97baa 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -57,6 +57,7 @@ static uint8_t lpfcAlpaArray[] = { | |||
57 | }; | 57 | }; |
58 | 58 | ||
59 | static void lpfc_disc_timeout_handler(struct lpfc_vport *); | 59 | static void lpfc_disc_timeout_handler(struct lpfc_vport *); |
60 | static void lpfc_disc_flush_list(struct lpfc_vport *vport); | ||
60 | 61 | ||
61 | void | 62 | void |
62 | lpfc_terminate_rport_io(struct fc_rport *rport) | 63 | lpfc_terminate_rport_io(struct fc_rport *rport) |
@@ -107,20 +108,14 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
107 | struct lpfc_nodelist * ndlp; | 108 | struct lpfc_nodelist * ndlp; |
108 | struct lpfc_vport *vport; | 109 | struct lpfc_vport *vport; |
109 | struct lpfc_hba *phba; | 110 | struct lpfc_hba *phba; |
110 | struct completion devloss_compl; | ||
111 | struct lpfc_work_evt *evtp; | 111 | struct lpfc_work_evt *evtp; |
112 | int put_node; | ||
113 | int put_rport; | ||
112 | 114 | ||
113 | rdata = rport->dd_data; | 115 | rdata = rport->dd_data; |
114 | ndlp = rdata->pnode; | 116 | ndlp = rdata->pnode; |
115 | 117 | if (!ndlp) | |
116 | if (!ndlp) { | ||
117 | if (rport->scsi_target_id != -1) { | ||
118 | printk(KERN_ERR "Cannot find remote node" | ||
119 | " for rport in dev_loss_tmo_callbk x%x\n", | ||
120 | rport->port_id); | ||
121 | } | ||
122 | return; | 118 | return; |
123 | } | ||
124 | 119 | ||
125 | vport = ndlp->vport; | 120 | vport = ndlp->vport; |
126 | phba = vport->phba; | 121 | phba = vport->phba; |
@@ -129,15 +124,35 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
129 | "rport devlosscb: sid:x%x did:x%x flg:x%x", | 124 | "rport devlosscb: sid:x%x did:x%x flg:x%x", |
130 | ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); | 125 | ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); |
131 | 126 | ||
132 | init_completion(&devloss_compl); | 127 | /* Don't defer this if we are in the process of deleting the vport |
128 | * or unloading the driver. The unload will cleanup the node | ||
129 | * appropriately we just need to cleanup the ndlp rport info here. | ||
130 | */ | ||
131 | if (vport->load_flag & FC_UNLOADING) { | ||
132 | put_node = rdata->pnode != NULL; | ||
133 | put_rport = ndlp->rport != NULL; | ||
134 | rdata->pnode = NULL; | ||
135 | ndlp->rport = NULL; | ||
136 | if (put_node) | ||
137 | lpfc_nlp_put(ndlp); | ||
138 | if (put_rport) | ||
139 | put_device(&rport->dev); | ||
140 | return; | ||
141 | } | ||
142 | |||
143 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) | ||
144 | return; | ||
145 | |||
133 | evtp = &ndlp->dev_loss_evt; | 146 | evtp = &ndlp->dev_loss_evt; |
134 | 147 | ||
135 | if (!list_empty(&evtp->evt_listp)) | 148 | if (!list_empty(&evtp->evt_listp)) |
136 | return; | 149 | return; |
137 | 150 | ||
138 | spin_lock_irq(&phba->hbalock); | 151 | spin_lock_irq(&phba->hbalock); |
139 | evtp->evt_arg1 = ndlp; | 152 | /* We need to hold the node by incrementing the reference |
140 | evtp->evt_arg2 = &devloss_compl; | 153 | * count until this queued work is done |
154 | */ | ||
155 | evtp->evt_arg1 = lpfc_nlp_get(ndlp); | ||
141 | evtp->evt = LPFC_EVT_DEV_LOSS; | 156 | evtp->evt = LPFC_EVT_DEV_LOSS; |
142 | list_add_tail(&evtp->evt_listp, &phba->work_list); | 157 | list_add_tail(&evtp->evt_listp, &phba->work_list); |
143 | if (phba->work_wait) | 158 | if (phba->work_wait) |
@@ -145,8 +160,6 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
145 | 160 | ||
146 | spin_unlock_irq(&phba->hbalock); | 161 | spin_unlock_irq(&phba->hbalock); |
147 | 162 | ||
148 | wait_for_completion(&devloss_compl); | ||
149 | |||
150 | return; | 163 | return; |
151 | } | 164 | } |
152 | 165 | ||
@@ -154,7 +167,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
154 | * This function is called from the worker thread when dev_loss_tmo | 167 | * This function is called from the worker thread when dev_loss_tmo |
155 | * expire. | 168 | * expire. |
156 | */ | 169 | */ |
157 | void | 170 | static void |
158 | lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | 171 | lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) |
159 | { | 172 | { |
160 | struct lpfc_rport_data *rdata; | 173 | struct lpfc_rport_data *rdata; |
@@ -162,6 +175,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
162 | struct lpfc_vport *vport; | 175 | struct lpfc_vport *vport; |
163 | struct lpfc_hba *phba; | 176 | struct lpfc_hba *phba; |
164 | uint8_t *name; | 177 | uint8_t *name; |
178 | int put_node; | ||
179 | int put_rport; | ||
165 | int warn_on = 0; | 180 | int warn_on = 0; |
166 | 181 | ||
167 | rport = ndlp->rport; | 182 | rport = ndlp->rport; |
@@ -178,14 +193,32 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
178 | "rport devlosstmo:did:x%x type:x%x id:x%x", | 193 | "rport devlosstmo:did:x%x type:x%x id:x%x", |
179 | ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id); | 194 | ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id); |
180 | 195 | ||
181 | if (!(vport->load_flag & FC_UNLOADING) && | 196 | /* Don't defer this if we are in the process of deleting the vport |
182 | ndlp->nlp_state == NLP_STE_MAPPED_NODE) | 197 | * or unloading the driver. The unload will cleanup the node |
198 | * appropriately we just need to cleanup the ndlp rport info here. | ||
199 | */ | ||
200 | if (vport->load_flag & FC_UNLOADING) { | ||
201 | if (ndlp->nlp_sid != NLP_NO_SID) { | ||
202 | /* flush the target */ | ||
203 | lpfc_sli_abort_iocb(vport, | ||
204 | &phba->sli.ring[phba->sli.fcp_ring], | ||
205 | ndlp->nlp_sid, 0, LPFC_CTX_TGT); | ||
206 | } | ||
207 | put_node = rdata->pnode != NULL; | ||
208 | put_rport = ndlp->rport != NULL; | ||
209 | rdata->pnode = NULL; | ||
210 | ndlp->rport = NULL; | ||
211 | if (put_node) | ||
212 | lpfc_nlp_put(ndlp); | ||
213 | if (put_rport) | ||
214 | put_device(&rport->dev); | ||
183 | return; | 215 | return; |
216 | } | ||
184 | 217 | ||
185 | if (ndlp->nlp_type & NLP_FABRIC) { | 218 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) |
186 | int put_node; | 219 | return; |
187 | int put_rport; | ||
188 | 220 | ||
221 | if (ndlp->nlp_type & NLP_FABRIC) { | ||
189 | /* We will clean up these Nodes in linkup */ | 222 | /* We will clean up these Nodes in linkup */ |
190 | put_node = rdata->pnode != NULL; | 223 | put_node = rdata->pnode != NULL; |
191 | put_rport = ndlp->rport != NULL; | 224 | put_rport = ndlp->rport != NULL; |
@@ -227,23 +260,20 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
227 | ndlp->nlp_state, ndlp->nlp_rpi); | 260 | ndlp->nlp_state, ndlp->nlp_rpi); |
228 | } | 261 | } |
229 | 262 | ||
263 | put_node = rdata->pnode != NULL; | ||
264 | put_rport = ndlp->rport != NULL; | ||
265 | rdata->pnode = NULL; | ||
266 | ndlp->rport = NULL; | ||
267 | if (put_node) | ||
268 | lpfc_nlp_put(ndlp); | ||
269 | if (put_rport) | ||
270 | put_device(&rport->dev); | ||
271 | |||
230 | if (!(vport->load_flag & FC_UNLOADING) && | 272 | if (!(vport->load_flag & FC_UNLOADING) && |
231 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && | 273 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && |
232 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 274 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
233 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) | 275 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) { |
234 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); | 276 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); |
235 | else { | ||
236 | int put_node; | ||
237 | int put_rport; | ||
238 | |||
239 | put_node = rdata->pnode != NULL; | ||
240 | put_rport = ndlp->rport != NULL; | ||
241 | rdata->pnode = NULL; | ||
242 | ndlp->rport = NULL; | ||
243 | if (put_node) | ||
244 | lpfc_nlp_put(ndlp); | ||
245 | if (put_rport) | ||
246 | put_device(&rport->dev); | ||
247 | } | 277 | } |
248 | } | 278 | } |
249 | 279 | ||
@@ -260,7 +290,6 @@ lpfc_work_list_done(struct lpfc_hba *phba) | |||
260 | { | 290 | { |
261 | struct lpfc_work_evt *evtp = NULL; | 291 | struct lpfc_work_evt *evtp = NULL; |
262 | struct lpfc_nodelist *ndlp; | 292 | struct lpfc_nodelist *ndlp; |
263 | struct lpfc_vport *vport; | ||
264 | int free_evt; | 293 | int free_evt; |
265 | 294 | ||
266 | spin_lock_irq(&phba->hbalock); | 295 | spin_lock_irq(&phba->hbalock); |
@@ -270,35 +299,22 @@ lpfc_work_list_done(struct lpfc_hba *phba) | |||
270 | spin_unlock_irq(&phba->hbalock); | 299 | spin_unlock_irq(&phba->hbalock); |
271 | free_evt = 1; | 300 | free_evt = 1; |
272 | switch (evtp->evt) { | 301 | switch (evtp->evt) { |
273 | case LPFC_EVT_DEV_LOSS_DELAY: | ||
274 | free_evt = 0; /* evt is part of ndlp */ | ||
275 | ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1); | ||
276 | vport = ndlp->vport; | ||
277 | if (!vport) | ||
278 | break; | ||
279 | |||
280 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT, | ||
281 | "rport devlossdly:did:x%x flg:x%x", | ||
282 | ndlp->nlp_DID, ndlp->nlp_flag, 0); | ||
283 | |||
284 | if (!(vport->load_flag & FC_UNLOADING) && | ||
285 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && | ||
286 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC)) { | ||
287 | lpfc_disc_state_machine(vport, ndlp, NULL, | ||
288 | NLP_EVT_DEVICE_RM); | ||
289 | } | ||
290 | break; | ||
291 | case LPFC_EVT_ELS_RETRY: | 302 | case LPFC_EVT_ELS_RETRY: |
292 | ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1); | 303 | ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1); |
293 | lpfc_els_retry_delay_handler(ndlp); | 304 | lpfc_els_retry_delay_handler(ndlp); |
294 | free_evt = 0; /* evt is part of ndlp */ | 305 | free_evt = 0; /* evt is part of ndlp */ |
306 | /* decrement the node reference count held | ||
307 | * for this queued work | ||
308 | */ | ||
309 | lpfc_nlp_put(ndlp); | ||
295 | break; | 310 | break; |
296 | case LPFC_EVT_DEV_LOSS: | 311 | case LPFC_EVT_DEV_LOSS: |
297 | ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); | 312 | ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); |
298 | lpfc_nlp_get(ndlp); | ||
299 | lpfc_dev_loss_tmo_handler(ndlp); | 313 | lpfc_dev_loss_tmo_handler(ndlp); |
300 | free_evt = 0; | 314 | free_evt = 0; |
301 | complete((struct completion *)(evtp->evt_arg2)); | 315 | /* decrement the node reference count held for |
316 | * this queued work | ||
317 | */ | ||
302 | lpfc_nlp_put(ndlp); | 318 | lpfc_nlp_put(ndlp); |
303 | break; | 319 | break; |
304 | case LPFC_EVT_ONLINE: | 320 | case LPFC_EVT_ONLINE: |
@@ -373,7 +389,7 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
373 | lpfc_handle_latt(phba); | 389 | lpfc_handle_latt(phba); |
374 | vports = lpfc_create_vport_work_array(phba); | 390 | vports = lpfc_create_vport_work_array(phba); |
375 | if (vports != NULL) | 391 | if (vports != NULL) |
376 | for(i = 0; i < LPFC_MAX_VPORTS; i++) { | 392 | for(i = 0; i <= phba->max_vpi; i++) { |
377 | /* | 393 | /* |
378 | * We could have no vports in array if unloading, so if | 394 | * We could have no vports in array if unloading, so if |
379 | * this happens then just use the pport | 395 | * this happens then just use the pport |
@@ -405,14 +421,14 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
405 | vport->work_port_events &= ~work_port_events; | 421 | vport->work_port_events &= ~work_port_events; |
406 | spin_unlock_irq(&vport->work_port_lock); | 422 | spin_unlock_irq(&vport->work_port_lock); |
407 | } | 423 | } |
408 | lpfc_destroy_vport_work_array(vports); | 424 | lpfc_destroy_vport_work_array(phba, vports); |
409 | 425 | ||
410 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 426 | pring = &phba->sli.ring[LPFC_ELS_RING]; |
411 | status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING))); | 427 | status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING))); |
412 | status >>= (4*LPFC_ELS_RING); | 428 | status >>= (4*LPFC_ELS_RING); |
413 | if ((status & HA_RXMASK) | 429 | if ((status & HA_RXMASK) |
414 | || (pring->flag & LPFC_DEFERRED_RING_EVENT)) { | 430 | || (pring->flag & LPFC_DEFERRED_RING_EVENT)) { |
415 | if (pring->flag & LPFC_STOP_IOCB_MASK) { | 431 | if (pring->flag & LPFC_STOP_IOCB_EVENT) { |
416 | pring->flag |= LPFC_DEFERRED_RING_EVENT; | 432 | pring->flag |= LPFC_DEFERRED_RING_EVENT; |
417 | } else { | 433 | } else { |
418 | lpfc_sli_handle_slow_ring_event(phba, pring, | 434 | lpfc_sli_handle_slow_ring_event(phba, pring, |
@@ -544,6 +560,7 @@ lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2, | |||
544 | void | 560 | void |
545 | lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) | 561 | lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) |
546 | { | 562 | { |
563 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
547 | struct lpfc_hba *phba = vport->phba; | 564 | struct lpfc_hba *phba = vport->phba; |
548 | struct lpfc_nodelist *ndlp, *next_ndlp; | 565 | struct lpfc_nodelist *ndlp, *next_ndlp; |
549 | int rc; | 566 | int rc; |
@@ -552,7 +569,9 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) | |||
552 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 569 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
553 | continue; | 570 | continue; |
554 | 571 | ||
555 | if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) | 572 | if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) || |
573 | ((vport->port_type == LPFC_NPIV_PORT) && | ||
574 | (ndlp->nlp_DID == NameServer_DID))) | ||
556 | lpfc_unreg_rpi(vport, ndlp); | 575 | lpfc_unreg_rpi(vport, ndlp); |
557 | 576 | ||
558 | /* Leave Fabric nodes alone on link down */ | 577 | /* Leave Fabric nodes alone on link down */ |
@@ -565,14 +584,30 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) | |||
565 | } | 584 | } |
566 | if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) { | 585 | if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) { |
567 | lpfc_mbx_unreg_vpi(vport); | 586 | lpfc_mbx_unreg_vpi(vport); |
587 | spin_lock_irq(shost->host_lock); | ||
568 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 588 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
589 | spin_unlock_irq(shost->host_lock); | ||
569 | } | 590 | } |
570 | } | 591 | } |
571 | 592 | ||
593 | void | ||
594 | lpfc_port_link_failure(struct lpfc_vport *vport) | ||
595 | { | ||
596 | /* Cleanup any outstanding RSCN activity */ | ||
597 | lpfc_els_flush_rscn(vport); | ||
598 | |||
599 | /* Cleanup any outstanding ELS commands */ | ||
600 | lpfc_els_flush_cmd(vport); | ||
601 | |||
602 | lpfc_cleanup_rpis(vport, 0); | ||
603 | |||
604 | /* Turn off discovery timer if its running */ | ||
605 | lpfc_can_disctmo(vport); | ||
606 | } | ||
607 | |||
572 | static void | 608 | static void |
573 | lpfc_linkdown_port(struct lpfc_vport *vport) | 609 | lpfc_linkdown_port(struct lpfc_vport *vport) |
574 | { | 610 | { |
575 | struct lpfc_nodelist *ndlp, *next_ndlp; | ||
576 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 611 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
577 | 612 | ||
578 | fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0); | 613 | fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0); |
@@ -581,21 +616,8 @@ lpfc_linkdown_port(struct lpfc_vport *vport) | |||
581 | "Link Down: state:x%x rtry:x%x flg:x%x", | 616 | "Link Down: state:x%x rtry:x%x flg:x%x", |
582 | vport->port_state, vport->fc_ns_retry, vport->fc_flag); | 617 | vport->port_state, vport->fc_ns_retry, vport->fc_flag); |
583 | 618 | ||
584 | /* Cleanup any outstanding RSCN activity */ | 619 | lpfc_port_link_failure(vport); |
585 | lpfc_els_flush_rscn(vport); | ||
586 | |||
587 | /* Cleanup any outstanding ELS commands */ | ||
588 | lpfc_els_flush_cmd(vport); | ||
589 | 620 | ||
590 | lpfc_cleanup_rpis(vport, 0); | ||
591 | |||
592 | /* free any ndlp's on unused list */ | ||
593 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) | ||
594 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | ||
595 | lpfc_drop_node(vport, ndlp); | ||
596 | |||
597 | /* Turn off discovery timer if its running */ | ||
598 | lpfc_can_disctmo(vport); | ||
599 | } | 621 | } |
600 | 622 | ||
601 | int | 623 | int |
@@ -618,18 +640,18 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
618 | spin_unlock_irq(&phba->hbalock); | 640 | spin_unlock_irq(&phba->hbalock); |
619 | vports = lpfc_create_vport_work_array(phba); | 641 | vports = lpfc_create_vport_work_array(phba); |
620 | if (vports != NULL) | 642 | if (vports != NULL) |
621 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 643 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
622 | /* Issue a LINK DOWN event to all nodes */ | 644 | /* Issue a LINK DOWN event to all nodes */ |
623 | lpfc_linkdown_port(vports[i]); | 645 | lpfc_linkdown_port(vports[i]); |
624 | } | 646 | } |
625 | lpfc_destroy_vport_work_array(vports); | 647 | lpfc_destroy_vport_work_array(phba, vports); |
626 | /* Clean up any firmware default rpi's */ | 648 | /* Clean up any firmware default rpi's */ |
627 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 649 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
628 | if (mb) { | 650 | if (mb) { |
629 | lpfc_unreg_did(phba, 0xffff, 0xffffffff, mb); | 651 | lpfc_unreg_did(phba, 0xffff, 0xffffffff, mb); |
630 | mb->vport = vport; | 652 | mb->vport = vport; |
631 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 653 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
632 | if (lpfc_sli_issue_mbox(phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB)) | 654 | if (lpfc_sli_issue_mbox(phba, mb, MBX_NOWAIT) |
633 | == MBX_NOT_FINISHED) { | 655 | == MBX_NOT_FINISHED) { |
634 | mempool_free(mb, phba->mbox_mem_pool); | 656 | mempool_free(mb, phba->mbox_mem_pool); |
635 | } | 657 | } |
@@ -643,8 +665,7 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
643 | lpfc_config_link(phba, mb); | 665 | lpfc_config_link(phba, mb); |
644 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 666 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
645 | mb->vport = vport; | 667 | mb->vport = vport; |
646 | if (lpfc_sli_issue_mbox(phba, mb, | 668 | if (lpfc_sli_issue_mbox(phba, mb, MBX_NOWAIT) |
647 | (MBX_NOWAIT | MBX_STOP_IOCB)) | ||
648 | == MBX_NOT_FINISHED) { | 669 | == MBX_NOT_FINISHED) { |
649 | mempool_free(mb, phba->mbox_mem_pool); | 670 | mempool_free(mb, phba->mbox_mem_pool); |
650 | } | 671 | } |
@@ -686,7 +707,6 @@ static void | |||
686 | lpfc_linkup_port(struct lpfc_vport *vport) | 707 | lpfc_linkup_port(struct lpfc_vport *vport) |
687 | { | 708 | { |
688 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 709 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
689 | struct lpfc_nodelist *ndlp, *next_ndlp; | ||
690 | struct lpfc_hba *phba = vport->phba; | 710 | struct lpfc_hba *phba = vport->phba; |
691 | 711 | ||
692 | if ((vport->load_flag & FC_UNLOADING) != 0) | 712 | if ((vport->load_flag & FC_UNLOADING) != 0) |
@@ -713,11 +733,6 @@ lpfc_linkup_port(struct lpfc_vport *vport) | |||
713 | if (vport->fc_flag & FC_LBIT) | 733 | if (vport->fc_flag & FC_LBIT) |
714 | lpfc_linkup_cleanup_nodes(vport); | 734 | lpfc_linkup_cleanup_nodes(vport); |
715 | 735 | ||
716 | /* free any ndlp's in unused state */ | ||
717 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, | ||
718 | nlp_listp) | ||
719 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | ||
720 | lpfc_drop_node(vport, ndlp); | ||
721 | } | 736 | } |
722 | 737 | ||
723 | static int | 738 | static int |
@@ -734,9 +749,9 @@ lpfc_linkup(struct lpfc_hba *phba) | |||
734 | 749 | ||
735 | vports = lpfc_create_vport_work_array(phba); | 750 | vports = lpfc_create_vport_work_array(phba); |
736 | if (vports != NULL) | 751 | if (vports != NULL) |
737 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) | 752 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) |
738 | lpfc_linkup_port(vports[i]); | 753 | lpfc_linkup_port(vports[i]); |
739 | lpfc_destroy_vport_work_array(vports); | 754 | lpfc_destroy_vport_work_array(phba, vports); |
740 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | 755 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) |
741 | lpfc_issue_clear_la(phba, phba->pport); | 756 | lpfc_issue_clear_la(phba, phba->pport); |
742 | 757 | ||
@@ -749,7 +764,7 @@ lpfc_linkup(struct lpfc_hba *phba) | |||
749 | * as the completion routine when the command is | 764 | * as the completion routine when the command is |
750 | * handed off to the SLI layer. | 765 | * handed off to the SLI layer. |
751 | */ | 766 | */ |
752 | void | 767 | static void |
753 | lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 768 | lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
754 | { | 769 | { |
755 | struct lpfc_vport *vport = pmb->vport; | 770 | struct lpfc_vport *vport = pmb->vport; |
@@ -852,8 +867,6 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
852 | * LPFC_FLOGI while waiting for FLOGI cmpl | 867 | * LPFC_FLOGI while waiting for FLOGI cmpl |
853 | */ | 868 | */ |
854 | if (vport->port_state != LPFC_FLOGI) { | 869 | if (vport->port_state != LPFC_FLOGI) { |
855 | vport->port_state = LPFC_FLOGI; | ||
856 | lpfc_set_disctmo(vport); | ||
857 | lpfc_initial_flogi(vport); | 870 | lpfc_initial_flogi(vport); |
858 | } | 871 | } |
859 | return; | 872 | return; |
@@ -1022,8 +1035,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
1022 | lpfc_read_sparam(phba, sparam_mbox, 0); | 1035 | lpfc_read_sparam(phba, sparam_mbox, 0); |
1023 | sparam_mbox->vport = vport; | 1036 | sparam_mbox->vport = vport; |
1024 | sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; | 1037 | sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; |
1025 | rc = lpfc_sli_issue_mbox(phba, sparam_mbox, | 1038 | rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT); |
1026 | (MBX_NOWAIT | MBX_STOP_IOCB)); | ||
1027 | if (rc == MBX_NOT_FINISHED) { | 1039 | if (rc == MBX_NOT_FINISHED) { |
1028 | mp = (struct lpfc_dmabuf *) sparam_mbox->context1; | 1040 | mp = (struct lpfc_dmabuf *) sparam_mbox->context1; |
1029 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1041 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
@@ -1040,8 +1052,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
1040 | lpfc_config_link(phba, cfglink_mbox); | 1052 | lpfc_config_link(phba, cfglink_mbox); |
1041 | cfglink_mbox->vport = vport; | 1053 | cfglink_mbox->vport = vport; |
1042 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; | 1054 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; |
1043 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, | 1055 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT); |
1044 | (MBX_NOWAIT | MBX_STOP_IOCB)); | ||
1045 | if (rc != MBX_NOT_FINISHED) | 1056 | if (rc != MBX_NOT_FINISHED) |
1046 | return; | 1057 | return; |
1047 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); | 1058 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); |
@@ -1174,6 +1185,9 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1174 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1185 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1175 | kfree(mp); | 1186 | kfree(mp); |
1176 | mempool_free(pmb, phba->mbox_mem_pool); | 1187 | mempool_free(pmb, phba->mbox_mem_pool); |
1188 | /* decrement the node reference count held for this callback | ||
1189 | * function. | ||
1190 | */ | ||
1177 | lpfc_nlp_put(ndlp); | 1191 | lpfc_nlp_put(ndlp); |
1178 | 1192 | ||
1179 | return; | 1193 | return; |
@@ -1219,7 +1233,7 @@ lpfc_mbx_unreg_vpi(struct lpfc_vport *vport) | |||
1219 | lpfc_unreg_vpi(phba, vport->vpi, mbox); | 1233 | lpfc_unreg_vpi(phba, vport->vpi, mbox); |
1220 | mbox->vport = vport; | 1234 | mbox->vport = vport; |
1221 | mbox->mbox_cmpl = lpfc_mbx_cmpl_unreg_vpi; | 1235 | mbox->mbox_cmpl = lpfc_mbx_cmpl_unreg_vpi; |
1222 | rc = lpfc_sli_issue_mbox(phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); | 1236 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
1223 | if (rc == MBX_NOT_FINISHED) { | 1237 | if (rc == MBX_NOT_FINISHED) { |
1224 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, | 1238 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, |
1225 | "1800 Could not issue unreg_vpi\n"); | 1239 | "1800 Could not issue unreg_vpi\n"); |
@@ -1319,7 +1333,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1319 | vports = lpfc_create_vport_work_array(phba); | 1333 | vports = lpfc_create_vport_work_array(phba); |
1320 | if (vports != NULL) | 1334 | if (vports != NULL) |
1321 | for(i = 0; | 1335 | for(i = 0; |
1322 | i < LPFC_MAX_VPORTS && vports[i] != NULL; | 1336 | i <= phba->max_vpi && vports[i] != NULL; |
1323 | i++) { | 1337 | i++) { |
1324 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | 1338 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) |
1325 | continue; | 1339 | continue; |
@@ -1335,7 +1349,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1335 | "Fabric support\n"); | 1349 | "Fabric support\n"); |
1336 | } | 1350 | } |
1337 | } | 1351 | } |
1338 | lpfc_destroy_vport_work_array(vports); | 1352 | lpfc_destroy_vport_work_array(phba, vports); |
1339 | lpfc_do_scr_ns_plogi(phba, vport); | 1353 | lpfc_do_scr_ns_plogi(phba, vport); |
1340 | } | 1354 | } |
1341 | 1355 | ||
@@ -1361,11 +1375,16 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1361 | 1375 | ||
1362 | if (mb->mbxStatus) { | 1376 | if (mb->mbxStatus) { |
1363 | out: | 1377 | out: |
1378 | /* decrement the node reference count held for this | ||
1379 | * callback function. | ||
1380 | */ | ||
1364 | lpfc_nlp_put(ndlp); | 1381 | lpfc_nlp_put(ndlp); |
1365 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1382 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1366 | kfree(mp); | 1383 | kfree(mp); |
1367 | mempool_free(pmb, phba->mbox_mem_pool); | 1384 | mempool_free(pmb, phba->mbox_mem_pool); |
1368 | lpfc_drop_node(vport, ndlp); | 1385 | |
1386 | /* If no other thread is using the ndlp, free it */ | ||
1387 | lpfc_nlp_not_used(ndlp); | ||
1369 | 1388 | ||
1370 | if (phba->fc_topology == TOPOLOGY_LOOP) { | 1389 | if (phba->fc_topology == TOPOLOGY_LOOP) { |
1371 | /* | 1390 | /* |
@@ -1410,6 +1429,9 @@ out: | |||
1410 | goto out; | 1429 | goto out; |
1411 | } | 1430 | } |
1412 | 1431 | ||
1432 | /* decrement the node reference count held for this | ||
1433 | * callback function. | ||
1434 | */ | ||
1413 | lpfc_nlp_put(ndlp); | 1435 | lpfc_nlp_put(ndlp); |
1414 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1436 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1415 | kfree(mp); | 1437 | kfree(mp); |
@@ -1656,8 +1678,18 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
1656 | void | 1678 | void |
1657 | lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | 1679 | lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1658 | { | 1680 | { |
1681 | /* | ||
1682 | * Use of lpfc_drop_node and UNUSED list: lpfc_drop_node should | ||
1683 | * be used if we wish to issue the "last" lpfc_nlp_put() to remove | ||
1684 | * the ndlp from the vport. The ndlp marked as UNUSED on the list | ||
1685 | * until ALL other outstanding threads have completed. We check | ||
1686 | * that the ndlp not already in the UNUSED state before we proceed. | ||
1687 | */ | ||
1688 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | ||
1689 | return; | ||
1659 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); | 1690 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
1660 | lpfc_nlp_put(ndlp); | 1691 | lpfc_nlp_put(ndlp); |
1692 | return; | ||
1661 | } | 1693 | } |
1662 | 1694 | ||
1663 | /* | 1695 | /* |
@@ -1868,8 +1900,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
1868 | lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox); | 1900 | lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox); |
1869 | mbox->vport = vport; | 1901 | mbox->vport = vport; |
1870 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1902 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
1871 | rc = lpfc_sli_issue_mbox(phba, mbox, | 1903 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
1872 | (MBX_NOWAIT | MBX_STOP_IOCB)); | ||
1873 | if (rc == MBX_NOT_FINISHED) | 1904 | if (rc == MBX_NOT_FINISHED) |
1874 | mempool_free(mbox, phba->mbox_mem_pool); | 1905 | mempool_free(mbox, phba->mbox_mem_pool); |
1875 | } | 1906 | } |
@@ -1892,8 +1923,8 @@ lpfc_unreg_all_rpis(struct lpfc_vport *vport) | |||
1892 | lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox); | 1923 | lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox); |
1893 | mbox->vport = vport; | 1924 | mbox->vport = vport; |
1894 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1925 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
1895 | rc = lpfc_sli_issue_mbox(phba, mbox, | 1926 | mbox->context1 = NULL; |
1896 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 1927 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); |
1897 | if (rc == MBX_NOT_FINISHED) { | 1928 | if (rc == MBX_NOT_FINISHED) { |
1898 | mempool_free(mbox, phba->mbox_mem_pool); | 1929 | mempool_free(mbox, phba->mbox_mem_pool); |
1899 | } | 1930 | } |
@@ -1912,8 +1943,8 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport) | |||
1912 | lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox); | 1943 | lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox); |
1913 | mbox->vport = vport; | 1944 | mbox->vport = vport; |
1914 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1945 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
1915 | rc = lpfc_sli_issue_mbox(phba, mbox, | 1946 | mbox->context1 = NULL; |
1916 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 1947 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); |
1917 | if (rc == MBX_NOT_FINISHED) { | 1948 | if (rc == MBX_NOT_FINISHED) { |
1918 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, | 1949 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, |
1919 | "1815 Could not issue " | 1950 | "1815 Could not issue " |
@@ -1981,11 +2012,6 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
1981 | if (!list_empty(&ndlp->dev_loss_evt.evt_listp)) | 2012 | if (!list_empty(&ndlp->dev_loss_evt.evt_listp)) |
1982 | list_del_init(&ndlp->dev_loss_evt.evt_listp); | 2013 | list_del_init(&ndlp->dev_loss_evt.evt_listp); |
1983 | 2014 | ||
1984 | if (!list_empty(&ndlp->dev_loss_evt.evt_listp)) { | ||
1985 | list_del_init(&ndlp->dev_loss_evt.evt_listp); | ||
1986 | complete((struct completion *)(ndlp->dev_loss_evt.evt_arg2)); | ||
1987 | } | ||
1988 | |||
1989 | lpfc_unreg_rpi(vport, ndlp); | 2015 | lpfc_unreg_rpi(vport, ndlp); |
1990 | 2016 | ||
1991 | return 0; | 2017 | return 0; |
@@ -1999,12 +2025,39 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
1999 | static void | 2025 | static void |
2000 | lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | 2026 | lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
2001 | { | 2027 | { |
2028 | struct lpfc_hba *phba = vport->phba; | ||
2002 | struct lpfc_rport_data *rdata; | 2029 | struct lpfc_rport_data *rdata; |
2030 | LPFC_MBOXQ_t *mbox; | ||
2031 | int rc; | ||
2003 | 2032 | ||
2004 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 2033 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
2005 | lpfc_cancel_retry_delay_tmo(vport, ndlp); | 2034 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
2006 | } | 2035 | } |
2007 | 2036 | ||
2037 | if (ndlp->nlp_flag & NLP_DEFER_RM && !ndlp->nlp_rpi) { | ||
2038 | /* For this case we need to cleanup the default rpi | ||
2039 | * allocated by the firmware. | ||
2040 | */ | ||
2041 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) | ||
2042 | != NULL) { | ||
2043 | rc = lpfc_reg_login(phba, vport->vpi, ndlp->nlp_DID, | ||
2044 | (uint8_t *) &vport->fc_sparam, mbox, 0); | ||
2045 | if (rc) { | ||
2046 | mempool_free(mbox, phba->mbox_mem_pool); | ||
2047 | } | ||
2048 | else { | ||
2049 | mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; | ||
2050 | mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | ||
2051 | mbox->vport = vport; | ||
2052 | mbox->context2 = NULL; | ||
2053 | rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
2054 | if (rc == MBX_NOT_FINISHED) { | ||
2055 | mempool_free(mbox, phba->mbox_mem_pool); | ||
2056 | } | ||
2057 | } | ||
2058 | } | ||
2059 | } | ||
2060 | |||
2008 | lpfc_cleanup_node(vport, ndlp); | 2061 | lpfc_cleanup_node(vport, ndlp); |
2009 | 2062 | ||
2010 | /* | 2063 | /* |
@@ -2132,6 +2185,12 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
2132 | } | 2185 | } |
2133 | if (vport->fc_flag & FC_RSCN_MODE) { | 2186 | if (vport->fc_flag & FC_RSCN_MODE) { |
2134 | if (lpfc_rscn_payload_check(vport, did)) { | 2187 | if (lpfc_rscn_payload_check(vport, did)) { |
2188 | /* If we've already recieved a PLOGI from this NPort | ||
2189 | * we don't need to try to discover it again. | ||
2190 | */ | ||
2191 | if (ndlp->nlp_flag & NLP_RCV_PLOGI) | ||
2192 | return NULL; | ||
2193 | |||
2135 | spin_lock_irq(shost->host_lock); | 2194 | spin_lock_irq(shost->host_lock); |
2136 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 2195 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
2137 | spin_unlock_irq(shost->host_lock); | 2196 | spin_unlock_irq(shost->host_lock); |
@@ -2144,8 +2203,13 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
2144 | } else | 2203 | } else |
2145 | ndlp = NULL; | 2204 | ndlp = NULL; |
2146 | } else { | 2205 | } else { |
2206 | /* If we've already recieved a PLOGI from this NPort, | ||
2207 | * or we are already in the process of discovery on it, | ||
2208 | * we don't need to try to discover it again. | ||
2209 | */ | ||
2147 | if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE || | 2210 | if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE || |
2148 | ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) | 2211 | ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || |
2212 | ndlp->nlp_flag & NLP_RCV_PLOGI) | ||
2149 | return NULL; | 2213 | return NULL; |
2150 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 2214 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
2151 | spin_lock_irq(shost->host_lock); | 2215 | spin_lock_irq(shost->host_lock); |
@@ -2220,8 +2284,7 @@ lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
2220 | lpfc_clear_la(phba, mbox); | 2284 | lpfc_clear_la(phba, mbox); |
2221 | mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 2285 | mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
2222 | mbox->vport = vport; | 2286 | mbox->vport = vport; |
2223 | rc = lpfc_sli_issue_mbox(phba, mbox, (MBX_NOWAIT | | 2287 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
2224 | MBX_STOP_IOCB)); | ||
2225 | if (rc == MBX_NOT_FINISHED) { | 2288 | if (rc == MBX_NOT_FINISHED) { |
2226 | mempool_free(mbox, phba->mbox_mem_pool); | 2289 | mempool_free(mbox, phba->mbox_mem_pool); |
2227 | lpfc_disc_flush_list(vport); | 2290 | lpfc_disc_flush_list(vport); |
@@ -2244,8 +2307,7 @@ lpfc_issue_reg_vpi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
2244 | lpfc_reg_vpi(phba, vport->vpi, vport->fc_myDID, regvpimbox); | 2307 | lpfc_reg_vpi(phba, vport->vpi, vport->fc_myDID, regvpimbox); |
2245 | regvpimbox->mbox_cmpl = lpfc_mbx_cmpl_reg_vpi; | 2308 | regvpimbox->mbox_cmpl = lpfc_mbx_cmpl_reg_vpi; |
2246 | regvpimbox->vport = vport; | 2309 | regvpimbox->vport = vport; |
2247 | if (lpfc_sli_issue_mbox(phba, regvpimbox, | 2310 | if (lpfc_sli_issue_mbox(phba, regvpimbox, MBX_NOWAIT) |
2248 | (MBX_NOWAIT | MBX_STOP_IOCB)) | ||
2249 | == MBX_NOT_FINISHED) { | 2311 | == MBX_NOT_FINISHED) { |
2250 | mempool_free(regvpimbox, phba->mbox_mem_pool); | 2312 | mempool_free(regvpimbox, phba->mbox_mem_pool); |
2251 | } | 2313 | } |
@@ -2414,7 +2476,7 @@ lpfc_free_tx(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
2414 | } | 2476 | } |
2415 | } | 2477 | } |
2416 | 2478 | ||
2417 | void | 2479 | static void |
2418 | lpfc_disc_flush_list(struct lpfc_vport *vport) | 2480 | lpfc_disc_flush_list(struct lpfc_vport *vport) |
2419 | { | 2481 | { |
2420 | struct lpfc_nodelist *ndlp, *next_ndlp; | 2482 | struct lpfc_nodelist *ndlp, *next_ndlp; |
@@ -2426,7 +2488,6 @@ lpfc_disc_flush_list(struct lpfc_vport *vport) | |||
2426 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || | 2488 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || |
2427 | ndlp->nlp_state == NLP_STE_ADISC_ISSUE) { | 2489 | ndlp->nlp_state == NLP_STE_ADISC_ISSUE) { |
2428 | lpfc_free_tx(phba, ndlp); | 2490 | lpfc_free_tx(phba, ndlp); |
2429 | lpfc_nlp_put(ndlp); | ||
2430 | } | 2491 | } |
2431 | } | 2492 | } |
2432 | } | 2493 | } |
@@ -2516,6 +2577,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) | |||
2516 | if (ndlp->nlp_type & NLP_FABRIC) { | 2577 | if (ndlp->nlp_type & NLP_FABRIC) { |
2517 | /* Clean up the ndlp on Fabric connections */ | 2578 | /* Clean up the ndlp on Fabric connections */ |
2518 | lpfc_drop_node(vport, ndlp); | 2579 | lpfc_drop_node(vport, ndlp); |
2580 | |||
2519 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 2581 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { |
2520 | /* Fail outstanding IO now since device | 2582 | /* Fail outstanding IO now since device |
2521 | * is marked for PLOGI. | 2583 | * is marked for PLOGI. |
@@ -2524,9 +2586,8 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) | |||
2524 | } | 2586 | } |
2525 | } | 2587 | } |
2526 | if (vport->port_state != LPFC_FLOGI) { | 2588 | if (vport->port_state != LPFC_FLOGI) { |
2527 | vport->port_state = LPFC_FLOGI; | ||
2528 | lpfc_set_disctmo(vport); | ||
2529 | lpfc_initial_flogi(vport); | 2589 | lpfc_initial_flogi(vport); |
2590 | return; | ||
2530 | } | 2591 | } |
2531 | break; | 2592 | break; |
2532 | 2593 | ||
@@ -2536,7 +2597,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) | |||
2536 | /* Initial FLOGI timeout */ | 2597 | /* Initial FLOGI timeout */ |
2537 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 2598 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
2538 | "0222 Initial %s timeout\n", | 2599 | "0222 Initial %s timeout\n", |
2539 | vport->vpi ? "FLOGI" : "FDISC"); | 2600 | vport->vpi ? "FDISC" : "FLOGI"); |
2540 | 2601 | ||
2541 | /* Assume no Fabric and go on with discovery. | 2602 | /* Assume no Fabric and go on with discovery. |
2542 | * Check for outstanding ELS FLOGI to abort. | 2603 | * Check for outstanding ELS FLOGI to abort. |
@@ -2558,10 +2619,10 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) | |||
2558 | /* Next look for NameServer ndlp */ | 2619 | /* Next look for NameServer ndlp */ |
2559 | ndlp = lpfc_findnode_did(vport, NameServer_DID); | 2620 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
2560 | if (ndlp) | 2621 | if (ndlp) |
2561 | lpfc_nlp_put(ndlp); | 2622 | lpfc_els_abort(phba, ndlp); |
2562 | /* Start discovery */ | 2623 | |
2563 | lpfc_disc_start(vport); | 2624 | /* ReStart discovery */ |
2564 | break; | 2625 | goto restart_disc; |
2565 | 2626 | ||
2566 | case LPFC_NS_QRY: | 2627 | case LPFC_NS_QRY: |
2567 | /* Check for wait for NameServer Rsp timeout */ | 2628 | /* Check for wait for NameServer Rsp timeout */ |
@@ -2580,6 +2641,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) | |||
2580 | } | 2641 | } |
2581 | vport->fc_ns_retry = 0; | 2642 | vport->fc_ns_retry = 0; |
2582 | 2643 | ||
2644 | restart_disc: | ||
2583 | /* | 2645 | /* |
2584 | * Discovery is over. | 2646 | * Discovery is over. |
2585 | * set port_state to PORT_READY if SLI2. | 2647 | * set port_state to PORT_READY if SLI2. |
@@ -2608,8 +2670,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) | |||
2608 | initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0; | 2670 | initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0; |
2609 | initlinkmbox->vport = vport; | 2671 | initlinkmbox->vport = vport; |
2610 | initlinkmbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 2672 | initlinkmbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
2611 | rc = lpfc_sli_issue_mbox(phba, initlinkmbox, | 2673 | rc = lpfc_sli_issue_mbox(phba, initlinkmbox, MBX_NOWAIT); |
2612 | (MBX_NOWAIT | MBX_STOP_IOCB)); | ||
2613 | lpfc_set_loopback_flag(phba); | 2674 | lpfc_set_loopback_flag(phba); |
2614 | if (rc == MBX_NOT_FINISHED) | 2675 | if (rc == MBX_NOT_FINISHED) |
2615 | mempool_free(initlinkmbox, phba->mbox_mem_pool); | 2676 | mempool_free(initlinkmbox, phba->mbox_mem_pool); |
@@ -2664,12 +2725,14 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) | |||
2664 | clrlaerr = 1; | 2725 | clrlaerr = 1; |
2665 | break; | 2726 | break; |
2666 | 2727 | ||
2728 | case LPFC_LINK_UP: | ||
2729 | lpfc_issue_clear_la(phba, vport); | ||
2730 | /* Drop thru */ | ||
2667 | case LPFC_LINK_UNKNOWN: | 2731 | case LPFC_LINK_UNKNOWN: |
2668 | case LPFC_WARM_START: | 2732 | case LPFC_WARM_START: |
2669 | case LPFC_INIT_START: | 2733 | case LPFC_INIT_START: |
2670 | case LPFC_INIT_MBX_CMDS: | 2734 | case LPFC_INIT_MBX_CMDS: |
2671 | case LPFC_LINK_DOWN: | 2735 | case LPFC_LINK_DOWN: |
2672 | case LPFC_LINK_UP: | ||
2673 | case LPFC_HBA_ERROR: | 2736 | case LPFC_HBA_ERROR: |
2674 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 2737 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
2675 | "0230 Unexpected timeout, hba link " | 2738 | "0230 Unexpected timeout, hba link " |
@@ -2723,7 +2786,9 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2723 | else | 2786 | else |
2724 | mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); | 2787 | mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); |
2725 | 2788 | ||
2726 | /* Mailbox took a reference to the node */ | 2789 | /* decrement the node reference count held for this callback |
2790 | * function. | ||
2791 | */ | ||
2727 | lpfc_nlp_put(ndlp); | 2792 | lpfc_nlp_put(ndlp); |
2728 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 2793 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
2729 | kfree(mp); | 2794 | kfree(mp); |
@@ -2747,19 +2812,19 @@ lpfc_filter_by_wwpn(struct lpfc_nodelist *ndlp, void *param) | |||
2747 | sizeof(ndlp->nlp_portname)) == 0; | 2812 | sizeof(ndlp->nlp_portname)) == 0; |
2748 | } | 2813 | } |
2749 | 2814 | ||
2750 | struct lpfc_nodelist * | 2815 | static struct lpfc_nodelist * |
2751 | __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) | 2816 | __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) |
2752 | { | 2817 | { |
2753 | struct lpfc_nodelist *ndlp; | 2818 | struct lpfc_nodelist *ndlp; |
2754 | 2819 | ||
2755 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { | 2820 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
2756 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE && | 2821 | if (filter(ndlp, param)) |
2757 | filter(ndlp, param)) | ||
2758 | return ndlp; | 2822 | return ndlp; |
2759 | } | 2823 | } |
2760 | return NULL; | 2824 | return NULL; |
2761 | } | 2825 | } |
2762 | 2826 | ||
2827 | #if 0 | ||
2763 | /* | 2828 | /* |
2764 | * Search node lists for a remote port matching filter criteria | 2829 | * Search node lists for a remote port matching filter criteria |
2765 | * Caller needs to hold host_lock before calling this routine. | 2830 | * Caller needs to hold host_lock before calling this routine. |
@@ -2775,6 +2840,7 @@ lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) | |||
2775 | spin_unlock_irq(shost->host_lock); | 2840 | spin_unlock_irq(shost->host_lock); |
2776 | return ndlp; | 2841 | return ndlp; |
2777 | } | 2842 | } |
2843 | #endif /* 0 */ | ||
2778 | 2844 | ||
2779 | /* | 2845 | /* |
2780 | * This routine looks up the ndlp lists for the given RPI. If rpi found it | 2846 | * This routine looks up the ndlp lists for the given RPI. If rpi found it |
@@ -2786,6 +2852,7 @@ __lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) | |||
2786 | return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); | 2852 | return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); |
2787 | } | 2853 | } |
2788 | 2854 | ||
2855 | #if 0 | ||
2789 | struct lpfc_nodelist * | 2856 | struct lpfc_nodelist * |
2790 | lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) | 2857 | lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) |
2791 | { | 2858 | { |
@@ -2797,6 +2864,7 @@ lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) | |||
2797 | spin_unlock_irq(shost->host_lock); | 2864 | spin_unlock_irq(shost->host_lock); |
2798 | return ndlp; | 2865 | return ndlp; |
2799 | } | 2866 | } |
2867 | #endif /* 0 */ | ||
2800 | 2868 | ||
2801 | /* | 2869 | /* |
2802 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it | 2870 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it |
@@ -2837,6 +2905,9 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
2837 | return; | 2905 | return; |
2838 | } | 2906 | } |
2839 | 2907 | ||
2908 | /* This routine releases all resources associated with a specifc NPort's ndlp | ||
2909 | * and mempool_free's the nodelist. | ||
2910 | */ | ||
2840 | static void | 2911 | static void |
2841 | lpfc_nlp_release(struct kref *kref) | 2912 | lpfc_nlp_release(struct kref *kref) |
2842 | { | 2913 | { |
@@ -2851,16 +2922,57 @@ lpfc_nlp_release(struct kref *kref) | |||
2851 | mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool); | 2922 | mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool); |
2852 | } | 2923 | } |
2853 | 2924 | ||
2925 | /* This routine bumps the reference count for a ndlp structure to ensure | ||
2926 | * that one discovery thread won't free a ndlp while another discovery thread | ||
2927 | * is using it. | ||
2928 | */ | ||
2854 | struct lpfc_nodelist * | 2929 | struct lpfc_nodelist * |
2855 | lpfc_nlp_get(struct lpfc_nodelist *ndlp) | 2930 | lpfc_nlp_get(struct lpfc_nodelist *ndlp) |
2856 | { | 2931 | { |
2857 | if (ndlp) | 2932 | if (ndlp) { |
2933 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, | ||
2934 | "node get: did:x%x flg:x%x refcnt:x%x", | ||
2935 | ndlp->nlp_DID, ndlp->nlp_flag, | ||
2936 | atomic_read(&ndlp->kref.refcount)); | ||
2858 | kref_get(&ndlp->kref); | 2937 | kref_get(&ndlp->kref); |
2938 | } | ||
2859 | return ndlp; | 2939 | return ndlp; |
2860 | } | 2940 | } |
2861 | 2941 | ||
2942 | |||
2943 | /* This routine decrements the reference count for a ndlp structure. If the | ||
2944 | * count goes to 0, this indicates the the associated nodelist should be freed. | ||
2945 | */ | ||
2862 | int | 2946 | int |
2863 | lpfc_nlp_put(struct lpfc_nodelist *ndlp) | 2947 | lpfc_nlp_put(struct lpfc_nodelist *ndlp) |
2864 | { | 2948 | { |
2949 | if (ndlp) { | ||
2950 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, | ||
2951 | "node put: did:x%x flg:x%x refcnt:x%x", | ||
2952 | ndlp->nlp_DID, ndlp->nlp_flag, | ||
2953 | atomic_read(&ndlp->kref.refcount)); | ||
2954 | } | ||
2865 | return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0; | 2955 | return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0; |
2866 | } | 2956 | } |
2957 | |||
2958 | /* This routine free's the specified nodelist if it is not in use | ||
2959 | * by any other discovery thread. This routine returns 1 if the ndlp | ||
2960 | * is not being used by anyone and has been freed. A return value of | ||
2961 | * 0 indicates it is being used by another discovery thread and the | ||
2962 | * refcount is left unchanged. | ||
2963 | */ | ||
2964 | int | ||
2965 | lpfc_nlp_not_used(struct lpfc_nodelist *ndlp) | ||
2966 | { | ||
2967 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, | ||
2968 | "node not used: did:x%x flg:x%x refcnt:x%x", | ||
2969 | ndlp->nlp_DID, ndlp->nlp_flag, | ||
2970 | atomic_read(&ndlp->kref.refcount)); | ||
2971 | |||
2972 | if (atomic_read(&ndlp->kref.refcount) == 1) { | ||
2973 | lpfc_nlp_put(ndlp); | ||
2974 | return 1; | ||
2975 | } | ||
2976 | return 0; | ||
2977 | } | ||
2978 | |||
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 451accd5564b..041f83e7634a 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -139,6 +139,9 @@ struct lpfc_sli_ct_request { | |||
139 | uint8_t len; | 139 | uint8_t len; |
140 | uint8_t symbname[255]; | 140 | uint8_t symbname[255]; |
141 | } rsnn; | 141 | } rsnn; |
142 | struct da_id { /* For DA_ID requests */ | ||
143 | uint32_t port_id; | ||
144 | } da_id; | ||
142 | struct rspn { /* For RSPN_ID requests */ | 145 | struct rspn { /* For RSPN_ID requests */ |
143 | uint32_t PortId; | 146 | uint32_t PortId; |
144 | uint8_t len; | 147 | uint8_t len; |
@@ -150,11 +153,7 @@ struct lpfc_sli_ct_request { | |||
150 | struct gff_acc { | 153 | struct gff_acc { |
151 | uint8_t fbits[128]; | 154 | uint8_t fbits[128]; |
152 | } gff_acc; | 155 | } gff_acc; |
153 | #ifdef __BIG_ENDIAN_BITFIELD | ||
154 | #define FCP_TYPE_FEATURE_OFFSET 7 | 156 | #define FCP_TYPE_FEATURE_OFFSET 7 |
155 | #else /* __LITTLE_ENDIAN_BITFIELD */ | ||
156 | #define FCP_TYPE_FEATURE_OFFSET 4 | ||
157 | #endif | ||
158 | struct rff { | 157 | struct rff { |
159 | uint32_t PortId; | 158 | uint32_t PortId; |
160 | uint8_t reserved[2]; | 159 | uint8_t reserved[2]; |
@@ -177,6 +176,8 @@ struct lpfc_sli_ct_request { | |||
177 | sizeof(struct rnn)) | 176 | sizeof(struct rnn)) |
178 | #define RSNN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \ | 177 | #define RSNN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \ |
179 | sizeof(struct rsnn)) | 178 | sizeof(struct rsnn)) |
179 | #define DA_ID_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \ | ||
180 | sizeof(struct da_id)) | ||
180 | #define RSPN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \ | 181 | #define RSPN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \ |
181 | sizeof(struct rspn)) | 182 | sizeof(struct rspn)) |
182 | 183 | ||
@@ -1228,7 +1229,8 @@ typedef struct { /* FireFly BIU registers */ | |||
1228 | #define HS_FFER3 0x20000000 /* Bit 29 */ | 1229 | #define HS_FFER3 0x20000000 /* Bit 29 */ |
1229 | #define HS_FFER2 0x40000000 /* Bit 30 */ | 1230 | #define HS_FFER2 0x40000000 /* Bit 30 */ |
1230 | #define HS_FFER1 0x80000000 /* Bit 31 */ | 1231 | #define HS_FFER1 0x80000000 /* Bit 31 */ |
1231 | #define HS_FFERM 0xFF000000 /* Mask for error bits 31:24 */ | 1232 | #define HS_CRIT_TEMP 0x00000100 /* Bit 8 */ |
1233 | #define HS_FFERM 0xFF000100 /* Mask for error bits 31:24 and 8 */ | ||
1232 | 1234 | ||
1233 | /* Host Control Register */ | 1235 | /* Host Control Register */ |
1234 | 1236 | ||
@@ -1277,12 +1279,14 @@ typedef struct { /* FireFly BIU registers */ | |||
1277 | #define MBX_DEL_LD_ENTRY 0x1D | 1279 | #define MBX_DEL_LD_ENTRY 0x1D |
1278 | #define MBX_RUN_PROGRAM 0x1E | 1280 | #define MBX_RUN_PROGRAM 0x1E |
1279 | #define MBX_SET_MASK 0x20 | 1281 | #define MBX_SET_MASK 0x20 |
1280 | #define MBX_SET_SLIM 0x21 | 1282 | #define MBX_SET_VARIABLE 0x21 |
1281 | #define MBX_UNREG_D_ID 0x23 | 1283 | #define MBX_UNREG_D_ID 0x23 |
1282 | #define MBX_KILL_BOARD 0x24 | 1284 | #define MBX_KILL_BOARD 0x24 |
1283 | #define MBX_CONFIG_FARP 0x25 | 1285 | #define MBX_CONFIG_FARP 0x25 |
1284 | #define MBX_BEACON 0x2A | 1286 | #define MBX_BEACON 0x2A |
1285 | #define MBX_HEARTBEAT 0x31 | 1287 | #define MBX_HEARTBEAT 0x31 |
1288 | #define MBX_WRITE_VPARMS 0x32 | ||
1289 | #define MBX_ASYNCEVT_ENABLE 0x33 | ||
1286 | 1290 | ||
1287 | #define MBX_CONFIG_HBQ 0x7C | 1291 | #define MBX_CONFIG_HBQ 0x7C |
1288 | #define MBX_LOAD_AREA 0x81 | 1292 | #define MBX_LOAD_AREA 0x81 |
@@ -1297,7 +1301,7 @@ typedef struct { /* FireFly BIU registers */ | |||
1297 | #define MBX_REG_VNPID 0x96 | 1301 | #define MBX_REG_VNPID 0x96 |
1298 | #define MBX_UNREG_VNPID 0x97 | 1302 | #define MBX_UNREG_VNPID 0x97 |
1299 | 1303 | ||
1300 | #define MBX_FLASH_WR_ULA 0x98 | 1304 | #define MBX_WRITE_WWN 0x98 |
1301 | #define MBX_SET_DEBUG 0x99 | 1305 | #define MBX_SET_DEBUG 0x99 |
1302 | #define MBX_LOAD_EXP_ROM 0x9C | 1306 | #define MBX_LOAD_EXP_ROM 0x9C |
1303 | 1307 | ||
@@ -1344,6 +1348,7 @@ typedef struct { /* FireFly BIU registers */ | |||
1344 | 1348 | ||
1345 | /* SLI_2 IOCB Command Set */ | 1349 | /* SLI_2 IOCB Command Set */ |
1346 | 1350 | ||
1351 | #define CMD_ASYNC_STATUS 0x7C | ||
1347 | #define CMD_RCV_SEQUENCE64_CX 0x81 | 1352 | #define CMD_RCV_SEQUENCE64_CX 0x81 |
1348 | #define CMD_XMIT_SEQUENCE64_CR 0x82 | 1353 | #define CMD_XMIT_SEQUENCE64_CR 0x82 |
1349 | #define CMD_XMIT_SEQUENCE64_CX 0x83 | 1354 | #define CMD_XMIT_SEQUENCE64_CX 0x83 |
@@ -1368,6 +1373,7 @@ typedef struct { /* FireFly BIU registers */ | |||
1368 | #define CMD_FCP_TRECEIVE64_CX 0xA1 | 1373 | #define CMD_FCP_TRECEIVE64_CX 0xA1 |
1369 | #define CMD_FCP_TRSP64_CX 0xA3 | 1374 | #define CMD_FCP_TRSP64_CX 0xA3 |
1370 | 1375 | ||
1376 | #define CMD_QUE_XRI64_CX 0xB3 | ||
1371 | #define CMD_IOCB_RCV_SEQ64_CX 0xB5 | 1377 | #define CMD_IOCB_RCV_SEQ64_CX 0xB5 |
1372 | #define CMD_IOCB_RCV_ELS64_CX 0xB7 | 1378 | #define CMD_IOCB_RCV_ELS64_CX 0xB7 |
1373 | #define CMD_IOCB_RCV_CONT64_CX 0xBB | 1379 | #define CMD_IOCB_RCV_CONT64_CX 0xBB |
@@ -1406,6 +1412,8 @@ typedef struct { /* FireFly BIU registers */ | |||
1406 | #define MBX_BUSY 0xffffff /* Attempted cmd to busy Mailbox */ | 1412 | #define MBX_BUSY 0xffffff /* Attempted cmd to busy Mailbox */ |
1407 | #define MBX_TIMEOUT 0xfffffe /* time-out expired waiting for */ | 1413 | #define MBX_TIMEOUT 0xfffffe /* time-out expired waiting for */ |
1408 | 1414 | ||
1415 | #define TEMPERATURE_OFFSET 0xB0 /* Slim offset for critical temperature event */ | ||
1416 | |||
1409 | /* | 1417 | /* |
1410 | * Begin Structure Definitions for Mailbox Commands | 1418 | * Begin Structure Definitions for Mailbox Commands |
1411 | */ | 1419 | */ |
@@ -2606,6 +2614,18 @@ typedef struct { | |||
2606 | uint32_t IPAddress; | 2614 | uint32_t IPAddress; |
2607 | } CONFIG_FARP_VAR; | 2615 | } CONFIG_FARP_VAR; |
2608 | 2616 | ||
2617 | /* Structure for MB Command MBX_ASYNCEVT_ENABLE (0x33) */ | ||
2618 | |||
2619 | typedef struct { | ||
2620 | #ifdef __BIG_ENDIAN_BITFIELD | ||
2621 | uint32_t rsvd:30; | ||
2622 | uint32_t ring:2; /* Ring for ASYNC_EVENT iocb Bits 0-1*/ | ||
2623 | #else /* __LITTLE_ENDIAN */ | ||
2624 | uint32_t ring:2; /* Ring for ASYNC_EVENT iocb Bits 0-1*/ | ||
2625 | uint32_t rsvd:30; | ||
2626 | #endif | ||
2627 | } ASYNCEVT_ENABLE_VAR; | ||
2628 | |||
2609 | /* Union of all Mailbox Command types */ | 2629 | /* Union of all Mailbox Command types */ |
2610 | #define MAILBOX_CMD_WSIZE 32 | 2630 | #define MAILBOX_CMD_WSIZE 32 |
2611 | #define MAILBOX_CMD_SIZE (MAILBOX_CMD_WSIZE * sizeof(uint32_t)) | 2631 | #define MAILBOX_CMD_SIZE (MAILBOX_CMD_WSIZE * sizeof(uint32_t)) |
@@ -2645,6 +2665,7 @@ typedef union { | |||
2645 | CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */ | 2665 | CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */ |
2646 | REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */ | 2666 | REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */ |
2647 | UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */ | 2667 | UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */ |
2668 | ASYNCEVT_ENABLE_VAR varCfgAsyncEvent; /*cmd = x33 (CONFIG_ASYNC) */ | ||
2648 | } MAILVARIANTS; | 2669 | } MAILVARIANTS; |
2649 | 2670 | ||
2650 | /* | 2671 | /* |
@@ -2973,6 +2994,34 @@ typedef struct { | |||
2973 | #endif | 2994 | #endif |
2974 | } RCV_ELS_REQ64; | 2995 | } RCV_ELS_REQ64; |
2975 | 2996 | ||
2997 | /* IOCB Command template for RCV_SEQ64 */ | ||
2998 | struct rcv_seq64 { | ||
2999 | struct ulp_bde64 elsReq; | ||
3000 | uint32_t hbq_1; | ||
3001 | uint32_t parmRo; | ||
3002 | #ifdef __BIG_ENDIAN_BITFIELD | ||
3003 | uint32_t rctl:8; | ||
3004 | uint32_t type:8; | ||
3005 | uint32_t dfctl:8; | ||
3006 | uint32_t ls:1; | ||
3007 | uint32_t fs:1; | ||
3008 | uint32_t rsvd2:3; | ||
3009 | uint32_t si:1; | ||
3010 | uint32_t bc:1; | ||
3011 | uint32_t rsvd3:1; | ||
3012 | #else /* __LITTLE_ENDIAN_BITFIELD */ | ||
3013 | uint32_t rsvd3:1; | ||
3014 | uint32_t bc:1; | ||
3015 | uint32_t si:1; | ||
3016 | uint32_t rsvd2:3; | ||
3017 | uint32_t fs:1; | ||
3018 | uint32_t ls:1; | ||
3019 | uint32_t dfctl:8; | ||
3020 | uint32_t type:8; | ||
3021 | uint32_t rctl:8; | ||
3022 | #endif | ||
3023 | }; | ||
3024 | |||
2976 | /* IOCB Command template for all 64 bit FCP Initiator commands */ | 3025 | /* IOCB Command template for all 64 bit FCP Initiator commands */ |
2977 | typedef struct { | 3026 | typedef struct { |
2978 | ULP_BDL bdl; | 3027 | ULP_BDL bdl; |
@@ -2987,6 +3036,21 @@ typedef struct { | |||
2987 | uint32_t fcpt_Length; /* transfer ready for IWRITE */ | 3036 | uint32_t fcpt_Length; /* transfer ready for IWRITE */ |
2988 | } FCPT_FIELDS64; | 3037 | } FCPT_FIELDS64; |
2989 | 3038 | ||
3039 | /* IOCB Command template for Async Status iocb commands */ | ||
3040 | typedef struct { | ||
3041 | uint32_t rsvd[4]; | ||
3042 | uint32_t param; | ||
3043 | #ifdef __BIG_ENDIAN_BITFIELD | ||
3044 | uint16_t evt_code; /* High order bits word 5 */ | ||
3045 | uint16_t sub_ctxt_tag; /* Low order bits word 5 */ | ||
3046 | #else /* __LITTLE_ENDIAN_BITFIELD */ | ||
3047 | uint16_t sub_ctxt_tag; /* High order bits word 5 */ | ||
3048 | uint16_t evt_code; /* Low order bits word 5 */ | ||
3049 | #endif | ||
3050 | } ASYNCSTAT_FIELDS; | ||
3051 | #define ASYNC_TEMP_WARN 0x100 | ||
3052 | #define ASYNC_TEMP_SAFE 0x101 | ||
3053 | |||
2990 | /* IOCB Command template for CMD_IOCB_RCV_ELS64_CX (0xB7) | 3054 | /* IOCB Command template for CMD_IOCB_RCV_ELS64_CX (0xB7) |
2991 | or CMD_IOCB_RCV_SEQ64_CX (0xB5) */ | 3055 | or CMD_IOCB_RCV_SEQ64_CX (0xB5) */ |
2992 | 3056 | ||
@@ -3004,7 +3068,26 @@ struct rcv_sli3 { | |||
3004 | struct ulp_bde64 bde2; | 3068 | struct ulp_bde64 bde2; |
3005 | }; | 3069 | }; |
3006 | 3070 | ||
3071 | /* Structure used for a single HBQ entry */ | ||
3072 | struct lpfc_hbq_entry { | ||
3073 | struct ulp_bde64 bde; | ||
3074 | uint32_t buffer_tag; | ||
3075 | }; | ||
3007 | 3076 | ||
3077 | /* IOCB Command template for QUE_XRI64_CX (0xB3) command */ | ||
3078 | typedef struct { | ||
3079 | struct lpfc_hbq_entry buff; | ||
3080 | uint32_t rsvd; | ||
3081 | uint32_t rsvd1; | ||
3082 | } QUE_XRI64_CX_FIELDS; | ||
3083 | |||
3084 | struct que_xri64cx_ext_fields { | ||
3085 | uint32_t iotag64_low; | ||
3086 | uint32_t iotag64_high; | ||
3087 | uint32_t ebde_count; | ||
3088 | uint32_t rsvd; | ||
3089 | struct lpfc_hbq_entry buff[5]; | ||
3090 | }; | ||
3008 | 3091 | ||
3009 | typedef struct _IOCB { /* IOCB structure */ | 3092 | typedef struct _IOCB { /* IOCB structure */ |
3010 | union { | 3093 | union { |
@@ -3028,6 +3111,9 @@ typedef struct _IOCB { /* IOCB structure */ | |||
3028 | XMT_SEQ_FIELDS64 xseq64; /* XMIT / BCAST cmd */ | 3111 | XMT_SEQ_FIELDS64 xseq64; /* XMIT / BCAST cmd */ |
3029 | FCPI_FIELDS64 fcpi64; /* FCP 64 bit Initiator template */ | 3112 | FCPI_FIELDS64 fcpi64; /* FCP 64 bit Initiator template */ |
3030 | FCPT_FIELDS64 fcpt64; /* FCP 64 bit target template */ | 3113 | FCPT_FIELDS64 fcpt64; /* FCP 64 bit target template */ |
3114 | ASYNCSTAT_FIELDS asyncstat; /* async_status iocb */ | ||
3115 | QUE_XRI64_CX_FIELDS quexri64cx; /* que_xri64_cx fields */ | ||
3116 | struct rcv_seq64 rcvseq64; /* RCV_SEQ64 and RCV_CONT64 */ | ||
3031 | 3117 | ||
3032 | uint32_t ulpWord[IOCB_WORD_SZ - 2]; /* generic 6 'words' */ | 3118 | uint32_t ulpWord[IOCB_WORD_SZ - 2]; /* generic 6 'words' */ |
3033 | } un; | 3119 | } un; |
@@ -3085,6 +3171,10 @@ typedef struct _IOCB { /* IOCB structure */ | |||
3085 | 3171 | ||
3086 | union { | 3172 | union { |
3087 | struct rcv_sli3 rcvsli3; /* words 8 - 15 */ | 3173 | struct rcv_sli3 rcvsli3; /* words 8 - 15 */ |
3174 | |||
3175 | /* words 8-31 used for que_xri_cx iocb */ | ||
3176 | struct que_xri64cx_ext_fields que_xri64cx_ext_words; | ||
3177 | |||
3088 | uint32_t sli3Words[24]; /* 96 extra bytes for SLI-3 */ | 3178 | uint32_t sli3Words[24]; /* 96 extra bytes for SLI-3 */ |
3089 | } unsli3; | 3179 | } unsli3; |
3090 | 3180 | ||
@@ -3124,12 +3214,6 @@ typedef struct _IOCB { /* IOCB structure */ | |||
3124 | 3214 | ||
3125 | } IOCB_t; | 3215 | } IOCB_t; |
3126 | 3216 | ||
3127 | /* Structure used for a single HBQ entry */ | ||
3128 | struct lpfc_hbq_entry { | ||
3129 | struct ulp_bde64 bde; | ||
3130 | uint32_t buffer_tag; | ||
3131 | }; | ||
3132 | |||
3133 | 3217 | ||
3134 | #define SLI1_SLIM_SIZE (4 * 1024) | 3218 | #define SLI1_SLIM_SIZE (4 * 1024) |
3135 | 3219 | ||
@@ -3172,6 +3256,8 @@ lpfc_is_LC_HBA(unsigned short device) | |||
3172 | (device == PCI_DEVICE_ID_BSMB) || | 3256 | (device == PCI_DEVICE_ID_BSMB) || |
3173 | (device == PCI_DEVICE_ID_ZMID) || | 3257 | (device == PCI_DEVICE_ID_ZMID) || |
3174 | (device == PCI_DEVICE_ID_ZSMB) || | 3258 | (device == PCI_DEVICE_ID_ZSMB) || |
3259 | (device == PCI_DEVICE_ID_SAT_MID) || | ||
3260 | (device == PCI_DEVICE_ID_SAT_SMB) || | ||
3175 | (device == PCI_DEVICE_ID_RFLY)) | 3261 | (device == PCI_DEVICE_ID_RFLY)) |
3176 | return 1; | 3262 | return 1; |
3177 | else | 3263 | else |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index ecebdfa00470..3205f7488d1c 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -212,6 +212,18 @@ out_free_mbox: | |||
212 | return 0; | 212 | return 0; |
213 | } | 213 | } |
214 | 214 | ||
215 | /* Completion handler for config async event mailbox command. */ | ||
216 | static void | ||
217 | lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) | ||
218 | { | ||
219 | if (pmboxq->mb.mbxStatus == MBX_SUCCESS) | ||
220 | phba->temp_sensor_support = 1; | ||
221 | else | ||
222 | phba->temp_sensor_support = 0; | ||
223 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
224 | return; | ||
225 | } | ||
226 | |||
215 | /************************************************************************/ | 227 | /************************************************************************/ |
216 | /* */ | 228 | /* */ |
217 | /* lpfc_config_port_post */ | 229 | /* lpfc_config_port_post */ |
@@ -234,6 +246,15 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
234 | int i, j; | 246 | int i, j; |
235 | int rc; | 247 | int rc; |
236 | 248 | ||
249 | spin_lock_irq(&phba->hbalock); | ||
250 | /* | ||
251 | * If the Config port completed correctly the HBA is not | ||
252 | * over heated any more. | ||
253 | */ | ||
254 | if (phba->over_temp_state == HBA_OVER_TEMP) | ||
255 | phba->over_temp_state = HBA_NORMAL_TEMP; | ||
256 | spin_unlock_irq(&phba->hbalock); | ||
257 | |||
237 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 258 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
238 | if (!pmb) { | 259 | if (!pmb) { |
239 | phba->link_state = LPFC_HBA_ERROR; | 260 | phba->link_state = LPFC_HBA_ERROR; |
@@ -343,7 +364,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
343 | 364 | ||
344 | phba->link_state = LPFC_LINK_DOWN; | 365 | phba->link_state = LPFC_LINK_DOWN; |
345 | 366 | ||
346 | /* Only process IOCBs on ring 0 till hba_state is READY */ | 367 | /* Only process IOCBs on ELS ring till hba_state is READY */ |
347 | if (psli->ring[psli->extra_ring].cmdringaddr) | 368 | if (psli->ring[psli->extra_ring].cmdringaddr) |
348 | psli->ring[psli->extra_ring].flag |= LPFC_STOP_IOCB_EVENT; | 369 | psli->ring[psli->extra_ring].flag |= LPFC_STOP_IOCB_EVENT; |
349 | if (psli->ring[psli->fcp_ring].cmdringaddr) | 370 | if (psli->ring[psli->fcp_ring].cmdringaddr) |
@@ -409,7 +430,21 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
409 | return -EIO; | 430 | return -EIO; |
410 | } | 431 | } |
411 | /* MBOX buffer will be freed in mbox compl */ | 432 | /* MBOX buffer will be freed in mbox compl */ |
433 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
434 | lpfc_config_async(phba, pmb, LPFC_ELS_RING); | ||
435 | pmb->mbox_cmpl = lpfc_config_async_cmpl; | ||
436 | pmb->vport = phba->pport; | ||
437 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | ||
412 | 438 | ||
439 | if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { | ||
440 | lpfc_printf_log(phba, | ||
441 | KERN_ERR, | ||
442 | LOG_INIT, | ||
443 | "0456 Adapter failed to issue " | ||
444 | "ASYNCEVT_ENABLE mbox status x%x \n.", | ||
445 | rc); | ||
446 | mempool_free(pmb, phba->mbox_mem_pool); | ||
447 | } | ||
413 | return (0); | 448 | return (0); |
414 | } | 449 | } |
415 | 450 | ||
@@ -449,6 +484,9 @@ lpfc_hba_down_post(struct lpfc_hba *phba) | |||
449 | struct lpfc_sli *psli = &phba->sli; | 484 | struct lpfc_sli *psli = &phba->sli; |
450 | struct lpfc_sli_ring *pring; | 485 | struct lpfc_sli_ring *pring; |
451 | struct lpfc_dmabuf *mp, *next_mp; | 486 | struct lpfc_dmabuf *mp, *next_mp; |
487 | struct lpfc_iocbq *iocb; | ||
488 | IOCB_t *cmd = NULL; | ||
489 | LIST_HEAD(completions); | ||
452 | int i; | 490 | int i; |
453 | 491 | ||
454 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) | 492 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) |
@@ -464,16 +502,42 @@ lpfc_hba_down_post(struct lpfc_hba *phba) | |||
464 | } | 502 | } |
465 | } | 503 | } |
466 | 504 | ||
505 | spin_lock_irq(&phba->hbalock); | ||
467 | for (i = 0; i < psli->num_rings; i++) { | 506 | for (i = 0; i < psli->num_rings; i++) { |
468 | pring = &psli->ring[i]; | 507 | pring = &psli->ring[i]; |
508 | |||
509 | /* At this point in time the HBA is either reset or DOA. Either | ||
510 | * way, nothing should be on txcmplq as it will NEVER complete. | ||
511 | */ | ||
512 | list_splice_init(&pring->txcmplq, &completions); | ||
513 | pring->txcmplq_cnt = 0; | ||
514 | spin_unlock_irq(&phba->hbalock); | ||
515 | |||
516 | while (!list_empty(&completions)) { | ||
517 | iocb = list_get_first(&completions, struct lpfc_iocbq, | ||
518 | list); | ||
519 | cmd = &iocb->iocb; | ||
520 | list_del_init(&iocb->list); | ||
521 | |||
522 | if (!iocb->iocb_cmpl) | ||
523 | lpfc_sli_release_iocbq(phba, iocb); | ||
524 | else { | ||
525 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
526 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
527 | (iocb->iocb_cmpl) (phba, iocb, iocb); | ||
528 | } | ||
529 | } | ||
530 | |||
469 | lpfc_sli_abort_iocb_ring(phba, pring); | 531 | lpfc_sli_abort_iocb_ring(phba, pring); |
532 | spin_lock_irq(&phba->hbalock); | ||
470 | } | 533 | } |
534 | spin_unlock_irq(&phba->hbalock); | ||
471 | 535 | ||
472 | return 0; | 536 | return 0; |
473 | } | 537 | } |
474 | 538 | ||
475 | /* HBA heart beat timeout handler */ | 539 | /* HBA heart beat timeout handler */ |
476 | void | 540 | static void |
477 | lpfc_hb_timeout(unsigned long ptr) | 541 | lpfc_hb_timeout(unsigned long ptr) |
478 | { | 542 | { |
479 | struct lpfc_hba *phba; | 543 | struct lpfc_hba *phba; |
@@ -512,8 +576,10 @@ void | |||
512 | lpfc_hb_timeout_handler(struct lpfc_hba *phba) | 576 | lpfc_hb_timeout_handler(struct lpfc_hba *phba) |
513 | { | 577 | { |
514 | LPFC_MBOXQ_t *pmboxq; | 578 | LPFC_MBOXQ_t *pmboxq; |
579 | struct lpfc_dmabuf *buf_ptr; | ||
515 | int retval; | 580 | int retval; |
516 | struct lpfc_sli *psli = &phba->sli; | 581 | struct lpfc_sli *psli = &phba->sli; |
582 | LIST_HEAD(completions); | ||
517 | 583 | ||
518 | if ((phba->link_state == LPFC_HBA_ERROR) || | 584 | if ((phba->link_state == LPFC_HBA_ERROR) || |
519 | (phba->pport->load_flag & FC_UNLOADING) || | 585 | (phba->pport->load_flag & FC_UNLOADING) || |
@@ -540,49 +606,88 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) | |||
540 | } | 606 | } |
541 | spin_unlock_irq(&phba->pport->work_port_lock); | 607 | spin_unlock_irq(&phba->pport->work_port_lock); |
542 | 608 | ||
543 | /* If there is no heart beat outstanding, issue a heartbeat command */ | 609 | if (phba->elsbuf_cnt && |
544 | if (!phba->hb_outstanding) { | 610 | (phba->elsbuf_cnt == phba->elsbuf_prev_cnt)) { |
545 | pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); | 611 | spin_lock_irq(&phba->hbalock); |
546 | if (!pmboxq) { | 612 | list_splice_init(&phba->elsbuf, &completions); |
547 | mod_timer(&phba->hb_tmofunc, | 613 | phba->elsbuf_cnt = 0; |
548 | jiffies + HZ * LPFC_HB_MBOX_INTERVAL); | 614 | phba->elsbuf_prev_cnt = 0; |
549 | return; | 615 | spin_unlock_irq(&phba->hbalock); |
616 | |||
617 | while (!list_empty(&completions)) { | ||
618 | list_remove_head(&completions, buf_ptr, | ||
619 | struct lpfc_dmabuf, list); | ||
620 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | ||
621 | kfree(buf_ptr); | ||
550 | } | 622 | } |
623 | } | ||
624 | phba->elsbuf_prev_cnt = phba->elsbuf_cnt; | ||
551 | 625 | ||
552 | lpfc_heart_beat(phba, pmboxq); | 626 | /* If there is no heart beat outstanding, issue a heartbeat command */ |
553 | pmboxq->mbox_cmpl = lpfc_hb_mbox_cmpl; | 627 | if (phba->cfg_enable_hba_heartbeat) { |
554 | pmboxq->vport = phba->pport; | 628 | if (!phba->hb_outstanding) { |
555 | retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); | 629 | pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); |
630 | if (!pmboxq) { | ||
631 | mod_timer(&phba->hb_tmofunc, | ||
632 | jiffies + HZ * LPFC_HB_MBOX_INTERVAL); | ||
633 | return; | ||
634 | } | ||
556 | 635 | ||
557 | if (retval != MBX_BUSY && retval != MBX_SUCCESS) { | 636 | lpfc_heart_beat(phba, pmboxq); |
558 | mempool_free(pmboxq, phba->mbox_mem_pool); | 637 | pmboxq->mbox_cmpl = lpfc_hb_mbox_cmpl; |
638 | pmboxq->vport = phba->pport; | ||
639 | retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); | ||
640 | |||
641 | if (retval != MBX_BUSY && retval != MBX_SUCCESS) { | ||
642 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
643 | mod_timer(&phba->hb_tmofunc, | ||
644 | jiffies + HZ * LPFC_HB_MBOX_INTERVAL); | ||
645 | return; | ||
646 | } | ||
559 | mod_timer(&phba->hb_tmofunc, | 647 | mod_timer(&phba->hb_tmofunc, |
560 | jiffies + HZ * LPFC_HB_MBOX_INTERVAL); | 648 | jiffies + HZ * LPFC_HB_MBOX_TIMEOUT); |
649 | phba->hb_outstanding = 1; | ||
561 | return; | 650 | return; |
651 | } else { | ||
652 | /* | ||
653 | * If heart beat timeout called with hb_outstanding set | ||
654 | * we need to take the HBA offline. | ||
655 | */ | ||
656 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
657 | "0459 Adapter heartbeat failure, " | ||
658 | "taking this port offline.\n"); | ||
659 | |||
660 | spin_lock_irq(&phba->hbalock); | ||
661 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
662 | spin_unlock_irq(&phba->hbalock); | ||
663 | |||
664 | lpfc_offline_prep(phba); | ||
665 | lpfc_offline(phba); | ||
666 | lpfc_unblock_mgmt_io(phba); | ||
667 | phba->link_state = LPFC_HBA_ERROR; | ||
668 | lpfc_hba_down_post(phba); | ||
562 | } | 669 | } |
563 | mod_timer(&phba->hb_tmofunc, | 670 | } |
564 | jiffies + HZ * LPFC_HB_MBOX_TIMEOUT); | 671 | } |
565 | phba->hb_outstanding = 1; | ||
566 | return; | ||
567 | } else { | ||
568 | /* | ||
569 | * If heart beat timeout called with hb_outstanding set we | ||
570 | * need to take the HBA offline. | ||
571 | */ | ||
572 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
573 | "0459 Adapter heartbeat failure, taking " | ||
574 | "this port offline.\n"); | ||
575 | 672 | ||
576 | spin_lock_irq(&phba->hbalock); | 673 | static void |
577 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 674 | lpfc_offline_eratt(struct lpfc_hba *phba) |
578 | spin_unlock_irq(&phba->hbalock); | 675 | { |
676 | struct lpfc_sli *psli = &phba->sli; | ||
579 | 677 | ||
580 | lpfc_offline_prep(phba); | 678 | spin_lock_irq(&phba->hbalock); |
581 | lpfc_offline(phba); | 679 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
582 | lpfc_unblock_mgmt_io(phba); | 680 | spin_unlock_irq(&phba->hbalock); |
583 | phba->link_state = LPFC_HBA_ERROR; | 681 | lpfc_offline_prep(phba); |
584 | lpfc_hba_down_post(phba); | 682 | |
585 | } | 683 | lpfc_offline(phba); |
684 | lpfc_reset_barrier(phba); | ||
685 | lpfc_sli_brdreset(phba); | ||
686 | lpfc_hba_down_post(phba); | ||
687 | lpfc_sli_brdready(phba, HS_MBRDY); | ||
688 | lpfc_unblock_mgmt_io(phba); | ||
689 | phba->link_state = LPFC_HBA_ERROR; | ||
690 | return; | ||
586 | } | 691 | } |
587 | 692 | ||
588 | /************************************************************************/ | 693 | /************************************************************************/ |
@@ -601,6 +706,8 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
601 | struct lpfc_sli_ring *pring; | 706 | struct lpfc_sli_ring *pring; |
602 | struct lpfc_vport **vports; | 707 | struct lpfc_vport **vports; |
603 | uint32_t event_data; | 708 | uint32_t event_data; |
709 | unsigned long temperature; | ||
710 | struct temp_event temp_event_data; | ||
604 | struct Scsi_Host *shost; | 711 | struct Scsi_Host *shost; |
605 | int i; | 712 | int i; |
606 | 713 | ||
@@ -608,6 +715,9 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
608 | * since we cannot communicate with the pci card anyway. */ | 715 | * since we cannot communicate with the pci card anyway. */ |
609 | if (pci_channel_offline(phba->pcidev)) | 716 | if (pci_channel_offline(phba->pcidev)) |
610 | return; | 717 | return; |
718 | /* If resets are disabled then leave the HBA alone and return */ | ||
719 | if (!phba->cfg_enable_hba_reset) | ||
720 | return; | ||
611 | 721 | ||
612 | if (phba->work_hs & HS_FFER6 || | 722 | if (phba->work_hs & HS_FFER6 || |
613 | phba->work_hs & HS_FFER5) { | 723 | phba->work_hs & HS_FFER5) { |
@@ -620,14 +730,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
620 | vports = lpfc_create_vport_work_array(phba); | 730 | vports = lpfc_create_vport_work_array(phba); |
621 | if (vports != NULL) | 731 | if (vports != NULL) |
622 | for(i = 0; | 732 | for(i = 0; |
623 | i < LPFC_MAX_VPORTS && vports[i] != NULL; | 733 | i <= phba->max_vpi && vports[i] != NULL; |
624 | i++){ | 734 | i++){ |
625 | shost = lpfc_shost_from_vport(vports[i]); | 735 | shost = lpfc_shost_from_vport(vports[i]); |
626 | spin_lock_irq(shost->host_lock); | 736 | spin_lock_irq(shost->host_lock); |
627 | vports[i]->fc_flag |= FC_ESTABLISH_LINK; | 737 | vports[i]->fc_flag |= FC_ESTABLISH_LINK; |
628 | spin_unlock_irq(shost->host_lock); | 738 | spin_unlock_irq(shost->host_lock); |
629 | } | 739 | } |
630 | lpfc_destroy_vport_work_array(vports); | 740 | lpfc_destroy_vport_work_array(phba, vports); |
631 | spin_lock_irq(&phba->hbalock); | 741 | spin_lock_irq(&phba->hbalock); |
632 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 742 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
633 | spin_unlock_irq(&phba->hbalock); | 743 | spin_unlock_irq(&phba->hbalock); |
@@ -655,6 +765,31 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
655 | return; | 765 | return; |
656 | } | 766 | } |
657 | lpfc_unblock_mgmt_io(phba); | 767 | lpfc_unblock_mgmt_io(phba); |
768 | } else if (phba->work_hs & HS_CRIT_TEMP) { | ||
769 | temperature = readl(phba->MBslimaddr + TEMPERATURE_OFFSET); | ||
770 | temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT; | ||
771 | temp_event_data.event_code = LPFC_CRIT_TEMP; | ||
772 | temp_event_data.data = (uint32_t)temperature; | ||
773 | |||
774 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
775 | "0459 Adapter maximum temperature exceeded " | ||
776 | "(%ld), taking this port offline " | ||
777 | "Data: x%x x%x x%x\n", | ||
778 | temperature, phba->work_hs, | ||
779 | phba->work_status[0], phba->work_status[1]); | ||
780 | |||
781 | shost = lpfc_shost_from_vport(phba->pport); | ||
782 | fc_host_post_vendor_event(shost, fc_get_event_number(), | ||
783 | sizeof(temp_event_data), | ||
784 | (char *) &temp_event_data, | ||
785 | SCSI_NL_VID_TYPE_PCI | ||
786 | | PCI_VENDOR_ID_EMULEX); | ||
787 | |||
788 | spin_lock_irq(&phba->hbalock); | ||
789 | phba->over_temp_state = HBA_OVER_TEMP; | ||
790 | spin_unlock_irq(&phba->hbalock); | ||
791 | lpfc_offline_eratt(phba); | ||
792 | |||
658 | } else { | 793 | } else { |
659 | /* The if clause above forces this code path when the status | 794 | /* The if clause above forces this code path when the status |
660 | * failure is a value other than FFER6. Do not call the offline | 795 | * failure is a value other than FFER6. Do not call the offline |
@@ -672,14 +807,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
672 | sizeof(event_data), (char *) &event_data, | 807 | sizeof(event_data), (char *) &event_data, |
673 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | 808 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); |
674 | 809 | ||
675 | spin_lock_irq(&phba->hbalock); | 810 | lpfc_offline_eratt(phba); |
676 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
677 | spin_unlock_irq(&phba->hbalock); | ||
678 | lpfc_offline_prep(phba); | ||
679 | lpfc_offline(phba); | ||
680 | lpfc_unblock_mgmt_io(phba); | ||
681 | phba->link_state = LPFC_HBA_ERROR; | ||
682 | lpfc_hba_down_post(phba); | ||
683 | } | 811 | } |
684 | } | 812 | } |
685 | 813 | ||
@@ -699,21 +827,25 @@ lpfc_handle_latt(struct lpfc_hba *phba) | |||
699 | LPFC_MBOXQ_t *pmb; | 827 | LPFC_MBOXQ_t *pmb; |
700 | volatile uint32_t control; | 828 | volatile uint32_t control; |
701 | struct lpfc_dmabuf *mp; | 829 | struct lpfc_dmabuf *mp; |
702 | int rc = -ENOMEM; | 830 | int rc = 0; |
703 | 831 | ||
704 | pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 832 | pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
705 | if (!pmb) | 833 | if (!pmb) { |
834 | rc = 1; | ||
706 | goto lpfc_handle_latt_err_exit; | 835 | goto lpfc_handle_latt_err_exit; |
836 | } | ||
707 | 837 | ||
708 | mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | 838 | mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); |
709 | if (!mp) | 839 | if (!mp) { |
840 | rc = 2; | ||
710 | goto lpfc_handle_latt_free_pmb; | 841 | goto lpfc_handle_latt_free_pmb; |
842 | } | ||
711 | 843 | ||
712 | mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); | 844 | mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); |
713 | if (!mp->virt) | 845 | if (!mp->virt) { |
846 | rc = 3; | ||
714 | goto lpfc_handle_latt_free_mp; | 847 | goto lpfc_handle_latt_free_mp; |
715 | 848 | } | |
716 | rc = -EIO; | ||
717 | 849 | ||
718 | /* Cleanup any outstanding ELS commands */ | 850 | /* Cleanup any outstanding ELS commands */ |
719 | lpfc_els_flush_all_cmd(phba); | 851 | lpfc_els_flush_all_cmd(phba); |
@@ -722,9 +854,11 @@ lpfc_handle_latt(struct lpfc_hba *phba) | |||
722 | lpfc_read_la(phba, pmb, mp); | 854 | lpfc_read_la(phba, pmb, mp); |
723 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; | 855 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; |
724 | pmb->vport = vport; | 856 | pmb->vport = vport; |
725 | rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); | 857 | rc = lpfc_sli_issue_mbox (phba, pmb, MBX_NOWAIT); |
726 | if (rc == MBX_NOT_FINISHED) | 858 | if (rc == MBX_NOT_FINISHED) { |
859 | rc = 4; | ||
727 | goto lpfc_handle_latt_free_mbuf; | 860 | goto lpfc_handle_latt_free_mbuf; |
861 | } | ||
728 | 862 | ||
729 | /* Clear Link Attention in HA REG */ | 863 | /* Clear Link Attention in HA REG */ |
730 | spin_lock_irq(&phba->hbalock); | 864 | spin_lock_irq(&phba->hbalock); |
@@ -756,10 +890,8 @@ lpfc_handle_latt_err_exit: | |||
756 | lpfc_linkdown(phba); | 890 | lpfc_linkdown(phba); |
757 | phba->link_state = LPFC_HBA_ERROR; | 891 | phba->link_state = LPFC_HBA_ERROR; |
758 | 892 | ||
759 | /* The other case is an error from issue_mbox */ | 893 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
760 | if (rc == -ENOMEM) | 894 | "0300 LATT: Cannot issue READ_LA: Data:%d\n", rc); |
761 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, | ||
762 | "0300 READ_LA: no buffers\n"); | ||
763 | 895 | ||
764 | return; | 896 | return; |
765 | } | 897 | } |
@@ -1088,9 +1220,8 @@ lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt, | |||
1088 | /* Allocate buffer to post */ | 1220 | /* Allocate buffer to post */ |
1089 | mp1 = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); | 1221 | mp1 = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); |
1090 | if (mp1) | 1222 | if (mp1) |
1091 | mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI, | 1223 | mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &mp1->phys); |
1092 | &mp1->phys); | 1224 | if (!mp1 || !mp1->virt) { |
1093 | if (mp1 == 0 || mp1->virt == 0) { | ||
1094 | kfree(mp1); | 1225 | kfree(mp1); |
1095 | lpfc_sli_release_iocbq(phba, iocb); | 1226 | lpfc_sli_release_iocbq(phba, iocb); |
1096 | pring->missbufcnt = cnt; | 1227 | pring->missbufcnt = cnt; |
@@ -1104,7 +1235,7 @@ lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt, | |||
1104 | if (mp2) | 1235 | if (mp2) |
1105 | mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI, | 1236 | mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI, |
1106 | &mp2->phys); | 1237 | &mp2->phys); |
1107 | if (mp2 == 0 || mp2->virt == 0) { | 1238 | if (!mp2 || !mp2->virt) { |
1108 | kfree(mp2); | 1239 | kfree(mp2); |
1109 | lpfc_mbuf_free(phba, mp1->virt, mp1->phys); | 1240 | lpfc_mbuf_free(phba, mp1->virt, mp1->phys); |
1110 | kfree(mp1); | 1241 | kfree(mp1); |
@@ -1280,15 +1411,39 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) | |||
1280 | kfree(HashWorking); | 1411 | kfree(HashWorking); |
1281 | } | 1412 | } |
1282 | 1413 | ||
1283 | static void | 1414 | void |
1284 | lpfc_cleanup(struct lpfc_vport *vport) | 1415 | lpfc_cleanup(struct lpfc_vport *vport) |
1285 | { | 1416 | { |
1417 | struct lpfc_hba *phba = vport->phba; | ||
1286 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1418 | struct lpfc_nodelist *ndlp, *next_ndlp; |
1419 | int i = 0; | ||
1287 | 1420 | ||
1288 | /* clean up phba - lpfc specific */ | 1421 | if (phba->link_state > LPFC_LINK_DOWN) |
1289 | lpfc_can_disctmo(vport); | 1422 | lpfc_port_link_failure(vport); |
1290 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) | 1423 | |
1291 | lpfc_nlp_put(ndlp); | 1424 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
1425 | if (ndlp->nlp_type & NLP_FABRIC) | ||
1426 | lpfc_disc_state_machine(vport, ndlp, NULL, | ||
1427 | NLP_EVT_DEVICE_RECOVERY); | ||
1428 | lpfc_disc_state_machine(vport, ndlp, NULL, | ||
1429 | NLP_EVT_DEVICE_RM); | ||
1430 | } | ||
1431 | |||
1432 | /* At this point, ALL ndlp's should be gone | ||
1433 | * because of the previous NLP_EVT_DEVICE_RM. | ||
1434 | * Lets wait for this to happen, if needed. | ||
1435 | */ | ||
1436 | while (!list_empty(&vport->fc_nodes)) { | ||
1437 | |||
1438 | if (i++ > 3000) { | ||
1439 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | ||
1440 | "0233 Nodelist not empty\n"); | ||
1441 | break; | ||
1442 | } | ||
1443 | |||
1444 | /* Wait for any activity on ndlps to settle */ | ||
1445 | msleep(10); | ||
1446 | } | ||
1292 | return; | 1447 | return; |
1293 | } | 1448 | } |
1294 | 1449 | ||
@@ -1307,14 +1462,14 @@ lpfc_establish_link_tmo(unsigned long ptr) | |||
1307 | phba->pport->fc_flag, phba->pport->port_state); | 1462 | phba->pport->fc_flag, phba->pport->port_state); |
1308 | vports = lpfc_create_vport_work_array(phba); | 1463 | vports = lpfc_create_vport_work_array(phba); |
1309 | if (vports != NULL) | 1464 | if (vports != NULL) |
1310 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 1465 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
1311 | struct Scsi_Host *shost; | 1466 | struct Scsi_Host *shost; |
1312 | shost = lpfc_shost_from_vport(vports[i]); | 1467 | shost = lpfc_shost_from_vport(vports[i]); |
1313 | spin_lock_irqsave(shost->host_lock, iflag); | 1468 | spin_lock_irqsave(shost->host_lock, iflag); |
1314 | vports[i]->fc_flag &= ~FC_ESTABLISH_LINK; | 1469 | vports[i]->fc_flag &= ~FC_ESTABLISH_LINK; |
1315 | spin_unlock_irqrestore(shost->host_lock, iflag); | 1470 | spin_unlock_irqrestore(shost->host_lock, iflag); |
1316 | } | 1471 | } |
1317 | lpfc_destroy_vport_work_array(vports); | 1472 | lpfc_destroy_vport_work_array(phba, vports); |
1318 | } | 1473 | } |
1319 | 1474 | ||
1320 | void | 1475 | void |
@@ -1339,6 +1494,16 @@ lpfc_stop_phba_timers(struct lpfc_hba *phba) | |||
1339 | return; | 1494 | return; |
1340 | } | 1495 | } |
1341 | 1496 | ||
1497 | static void | ||
1498 | lpfc_block_mgmt_io(struct lpfc_hba * phba) | ||
1499 | { | ||
1500 | unsigned long iflag; | ||
1501 | |||
1502 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
1503 | phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO; | ||
1504 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
1505 | } | ||
1506 | |||
1342 | int | 1507 | int |
1343 | lpfc_online(struct lpfc_hba *phba) | 1508 | lpfc_online(struct lpfc_hba *phba) |
1344 | { | 1509 | { |
@@ -1369,7 +1534,7 @@ lpfc_online(struct lpfc_hba *phba) | |||
1369 | 1534 | ||
1370 | vports = lpfc_create_vport_work_array(phba); | 1535 | vports = lpfc_create_vport_work_array(phba); |
1371 | if (vports != NULL) | 1536 | if (vports != NULL) |
1372 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 1537 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
1373 | struct Scsi_Host *shost; | 1538 | struct Scsi_Host *shost; |
1374 | shost = lpfc_shost_from_vport(vports[i]); | 1539 | shost = lpfc_shost_from_vport(vports[i]); |
1375 | spin_lock_irq(shost->host_lock); | 1540 | spin_lock_irq(shost->host_lock); |
@@ -1378,23 +1543,13 @@ lpfc_online(struct lpfc_hba *phba) | |||
1378 | vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 1543 | vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
1379 | spin_unlock_irq(shost->host_lock); | 1544 | spin_unlock_irq(shost->host_lock); |
1380 | } | 1545 | } |
1381 | lpfc_destroy_vport_work_array(vports); | 1546 | lpfc_destroy_vport_work_array(phba, vports); |
1382 | 1547 | ||
1383 | lpfc_unblock_mgmt_io(phba); | 1548 | lpfc_unblock_mgmt_io(phba); |
1384 | return 0; | 1549 | return 0; |
1385 | } | 1550 | } |
1386 | 1551 | ||
1387 | void | 1552 | void |
1388 | lpfc_block_mgmt_io(struct lpfc_hba * phba) | ||
1389 | { | ||
1390 | unsigned long iflag; | ||
1391 | |||
1392 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
1393 | phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO; | ||
1394 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
1395 | } | ||
1396 | |||
1397 | void | ||
1398 | lpfc_unblock_mgmt_io(struct lpfc_hba * phba) | 1553 | lpfc_unblock_mgmt_io(struct lpfc_hba * phba) |
1399 | { | 1554 | { |
1400 | unsigned long iflag; | 1555 | unsigned long iflag; |
@@ -1409,6 +1564,8 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
1409 | { | 1564 | { |
1410 | struct lpfc_vport *vport = phba->pport; | 1565 | struct lpfc_vport *vport = phba->pport; |
1411 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1566 | struct lpfc_nodelist *ndlp, *next_ndlp; |
1567 | struct lpfc_vport **vports; | ||
1568 | int i; | ||
1412 | 1569 | ||
1413 | if (vport->fc_flag & FC_OFFLINE_MODE) | 1570 | if (vport->fc_flag & FC_OFFLINE_MODE) |
1414 | return; | 1571 | return; |
@@ -1417,10 +1574,34 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
1417 | 1574 | ||
1418 | lpfc_linkdown(phba); | 1575 | lpfc_linkdown(phba); |
1419 | 1576 | ||
1420 | /* Issue an unreg_login to all nodes */ | 1577 | /* Issue an unreg_login to all nodes on all vports */ |
1421 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) | 1578 | vports = lpfc_create_vport_work_array(phba); |
1422 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) | 1579 | if (vports != NULL) { |
1423 | lpfc_unreg_rpi(vport, ndlp); | 1580 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
1581 | struct Scsi_Host *shost; | ||
1582 | |||
1583 | if (vports[i]->load_flag & FC_UNLOADING) | ||
1584 | continue; | ||
1585 | shost = lpfc_shost_from_vport(vports[i]); | ||
1586 | list_for_each_entry_safe(ndlp, next_ndlp, | ||
1587 | &vports[i]->fc_nodes, | ||
1588 | nlp_listp) { | ||
1589 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | ||
1590 | continue; | ||
1591 | if (ndlp->nlp_type & NLP_FABRIC) { | ||
1592 | lpfc_disc_state_machine(vports[i], ndlp, | ||
1593 | NULL, NLP_EVT_DEVICE_RECOVERY); | ||
1594 | lpfc_disc_state_machine(vports[i], ndlp, | ||
1595 | NULL, NLP_EVT_DEVICE_RM); | ||
1596 | } | ||
1597 | spin_lock_irq(shost->host_lock); | ||
1598 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | ||
1599 | spin_unlock_irq(shost->host_lock); | ||
1600 | lpfc_unreg_rpi(vports[i], ndlp); | ||
1601 | } | ||
1602 | } | ||
1603 | } | ||
1604 | lpfc_destroy_vport_work_array(phba, vports); | ||
1424 | 1605 | ||
1425 | lpfc_sli_flush_mbox_queue(phba); | 1606 | lpfc_sli_flush_mbox_queue(phba); |
1426 | } | 1607 | } |
@@ -1439,9 +1620,9 @@ lpfc_offline(struct lpfc_hba *phba) | |||
1439 | lpfc_stop_phba_timers(phba); | 1620 | lpfc_stop_phba_timers(phba); |
1440 | vports = lpfc_create_vport_work_array(phba); | 1621 | vports = lpfc_create_vport_work_array(phba); |
1441 | if (vports != NULL) | 1622 | if (vports != NULL) |
1442 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) | 1623 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) |
1443 | lpfc_stop_vport_timers(vports[i]); | 1624 | lpfc_stop_vport_timers(vports[i]); |
1444 | lpfc_destroy_vport_work_array(vports); | 1625 | lpfc_destroy_vport_work_array(phba, vports); |
1445 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | 1626 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, |
1446 | "0460 Bring Adapter offline\n"); | 1627 | "0460 Bring Adapter offline\n"); |
1447 | /* Bring down the SLI Layer and cleanup. The HBA is offline | 1628 | /* Bring down the SLI Layer and cleanup. The HBA is offline |
@@ -1452,15 +1633,14 @@ lpfc_offline(struct lpfc_hba *phba) | |||
1452 | spin_unlock_irq(&phba->hbalock); | 1633 | spin_unlock_irq(&phba->hbalock); |
1453 | vports = lpfc_create_vport_work_array(phba); | 1634 | vports = lpfc_create_vport_work_array(phba); |
1454 | if (vports != NULL) | 1635 | if (vports != NULL) |
1455 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 1636 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
1456 | shost = lpfc_shost_from_vport(vports[i]); | 1637 | shost = lpfc_shost_from_vport(vports[i]); |
1457 | lpfc_cleanup(vports[i]); | ||
1458 | spin_lock_irq(shost->host_lock); | 1638 | spin_lock_irq(shost->host_lock); |
1459 | vports[i]->work_port_events = 0; | 1639 | vports[i]->work_port_events = 0; |
1460 | vports[i]->fc_flag |= FC_OFFLINE_MODE; | 1640 | vports[i]->fc_flag |= FC_OFFLINE_MODE; |
1461 | spin_unlock_irq(shost->host_lock); | 1641 | spin_unlock_irq(shost->host_lock); |
1462 | } | 1642 | } |
1463 | lpfc_destroy_vport_work_array(vports); | 1643 | lpfc_destroy_vport_work_array(phba, vports); |
1464 | } | 1644 | } |
1465 | 1645 | ||
1466 | /****************************************************************************** | 1646 | /****************************************************************************** |
@@ -1674,6 +1854,8 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost) | |||
1674 | fc_host_supported_speeds(shost) = 0; | 1854 | fc_host_supported_speeds(shost) = 0; |
1675 | if (phba->lmt & LMT_10Gb) | 1855 | if (phba->lmt & LMT_10Gb) |
1676 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT; | 1856 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT; |
1857 | if (phba->lmt & LMT_8Gb) | ||
1858 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_8GBIT; | ||
1677 | if (phba->lmt & LMT_4Gb) | 1859 | if (phba->lmt & LMT_4Gb) |
1678 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT; | 1860 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT; |
1679 | if (phba->lmt & LMT_2Gb) | 1861 | if (phba->lmt & LMT_2Gb) |
@@ -1707,13 +1889,14 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1707 | struct Scsi_Host *shost = NULL; | 1889 | struct Scsi_Host *shost = NULL; |
1708 | void *ptr; | 1890 | void *ptr; |
1709 | unsigned long bar0map_len, bar2map_len; | 1891 | unsigned long bar0map_len, bar2map_len; |
1710 | int error = -ENODEV; | 1892 | int error = -ENODEV, retval; |
1711 | int i, hbq_count; | 1893 | int i, hbq_count; |
1712 | uint16_t iotag; | 1894 | uint16_t iotag; |
1895 | int bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
1713 | 1896 | ||
1714 | if (pci_enable_device(pdev)) | 1897 | if (pci_enable_device_bars(pdev, bars)) |
1715 | goto out; | 1898 | goto out; |
1716 | if (pci_request_regions(pdev, LPFC_DRIVER_NAME)) | 1899 | if (pci_request_selected_regions(pdev, bars, LPFC_DRIVER_NAME)) |
1717 | goto out_disable_device; | 1900 | goto out_disable_device; |
1718 | 1901 | ||
1719 | phba = kzalloc(sizeof (struct lpfc_hba), GFP_KERNEL); | 1902 | phba = kzalloc(sizeof (struct lpfc_hba), GFP_KERNEL); |
@@ -1823,9 +2006,11 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1823 | lpfc_sli_setup(phba); | 2006 | lpfc_sli_setup(phba); |
1824 | lpfc_sli_queue_setup(phba); | 2007 | lpfc_sli_queue_setup(phba); |
1825 | 2008 | ||
1826 | error = lpfc_mem_alloc(phba); | 2009 | retval = lpfc_mem_alloc(phba); |
1827 | if (error) | 2010 | if (retval) { |
2011 | error = retval; | ||
1828 | goto out_free_hbqslimp; | 2012 | goto out_free_hbqslimp; |
2013 | } | ||
1829 | 2014 | ||
1830 | /* Initialize and populate the iocb list per host. */ | 2015 | /* Initialize and populate the iocb list per host. */ |
1831 | INIT_LIST_HEAD(&phba->lpfc_iocb_list); | 2016 | INIT_LIST_HEAD(&phba->lpfc_iocb_list); |
@@ -1880,6 +2065,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1880 | /* Initialize list of fabric iocbs */ | 2065 | /* Initialize list of fabric iocbs */ |
1881 | INIT_LIST_HEAD(&phba->fabric_iocb_list); | 2066 | INIT_LIST_HEAD(&phba->fabric_iocb_list); |
1882 | 2067 | ||
2068 | /* Initialize list to save ELS buffers */ | ||
2069 | INIT_LIST_HEAD(&phba->elsbuf); | ||
2070 | |||
1883 | vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev); | 2071 | vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev); |
1884 | if (!vport) | 2072 | if (!vport) |
1885 | goto out_kthread_stop; | 2073 | goto out_kthread_stop; |
@@ -1891,8 +2079,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1891 | pci_set_drvdata(pdev, shost); | 2079 | pci_set_drvdata(pdev, shost); |
1892 | 2080 | ||
1893 | if (phba->cfg_use_msi) { | 2081 | if (phba->cfg_use_msi) { |
1894 | error = pci_enable_msi(phba->pcidev); | 2082 | retval = pci_enable_msi(phba->pcidev); |
1895 | if (!error) | 2083 | if (!retval) |
1896 | phba->using_msi = 1; | 2084 | phba->using_msi = 1; |
1897 | else | 2085 | else |
1898 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 2086 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
@@ -1900,11 +2088,12 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1900 | "with IRQ\n"); | 2088 | "with IRQ\n"); |
1901 | } | 2089 | } |
1902 | 2090 | ||
1903 | error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, | 2091 | retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, |
1904 | LPFC_DRIVER_NAME, phba); | 2092 | LPFC_DRIVER_NAME, phba); |
1905 | if (error) { | 2093 | if (retval) { |
1906 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2094 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1907 | "0451 Enable interrupt handler failed\n"); | 2095 | "0451 Enable interrupt handler failed\n"); |
2096 | error = retval; | ||
1908 | goto out_disable_msi; | 2097 | goto out_disable_msi; |
1909 | } | 2098 | } |
1910 | 2099 | ||
@@ -1914,11 +2103,15 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1914 | phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; | 2103 | phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; |
1915 | phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; | 2104 | phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; |
1916 | 2105 | ||
1917 | if (lpfc_alloc_sysfs_attr(vport)) | 2106 | if (lpfc_alloc_sysfs_attr(vport)) { |
2107 | error = -ENOMEM; | ||
1918 | goto out_free_irq; | 2108 | goto out_free_irq; |
2109 | } | ||
1919 | 2110 | ||
1920 | if (lpfc_sli_hba_setup(phba)) | 2111 | if (lpfc_sli_hba_setup(phba)) { |
2112 | error = -ENODEV; | ||
1921 | goto out_remove_device; | 2113 | goto out_remove_device; |
2114 | } | ||
1922 | 2115 | ||
1923 | /* | 2116 | /* |
1924 | * hba setup may have changed the hba_queue_depth so we need to adjust | 2117 | * hba setup may have changed the hba_queue_depth so we need to adjust |
@@ -1975,7 +2168,7 @@ out_idr_remove: | |||
1975 | out_free_phba: | 2168 | out_free_phba: |
1976 | kfree(phba); | 2169 | kfree(phba); |
1977 | out_release_regions: | 2170 | out_release_regions: |
1978 | pci_release_regions(pdev); | 2171 | pci_release_selected_regions(pdev, bars); |
1979 | out_disable_device: | 2172 | out_disable_device: |
1980 | pci_disable_device(pdev); | 2173 | pci_disable_device(pdev); |
1981 | out: | 2174 | out: |
@@ -1991,6 +2184,8 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
1991 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 2184 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
1992 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 2185 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1993 | struct lpfc_hba *phba = vport->phba; | 2186 | struct lpfc_hba *phba = vport->phba; |
2187 | int bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
2188 | |||
1994 | spin_lock_irq(&phba->hbalock); | 2189 | spin_lock_irq(&phba->hbalock); |
1995 | vport->load_flag |= FC_UNLOADING; | 2190 | vport->load_flag |= FC_UNLOADING; |
1996 | spin_unlock_irq(&phba->hbalock); | 2191 | spin_unlock_irq(&phba->hbalock); |
@@ -1998,8 +2193,12 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
1998 | kfree(vport->vname); | 2193 | kfree(vport->vname); |
1999 | lpfc_free_sysfs_attr(vport); | 2194 | lpfc_free_sysfs_attr(vport); |
2000 | 2195 | ||
2196 | kthread_stop(phba->worker_thread); | ||
2197 | |||
2001 | fc_remove_host(shost); | 2198 | fc_remove_host(shost); |
2002 | scsi_remove_host(shost); | 2199 | scsi_remove_host(shost); |
2200 | lpfc_cleanup(vport); | ||
2201 | |||
2003 | /* | 2202 | /* |
2004 | * Bring down the SLI Layer. This step disable all interrupts, | 2203 | * Bring down the SLI Layer. This step disable all interrupts, |
2005 | * clears the rings, discards all mailbox commands, and resets | 2204 | * clears the rings, discards all mailbox commands, and resets |
@@ -2014,9 +2213,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
2014 | spin_unlock_irq(&phba->hbalock); | 2213 | spin_unlock_irq(&phba->hbalock); |
2015 | 2214 | ||
2016 | lpfc_debugfs_terminate(vport); | 2215 | lpfc_debugfs_terminate(vport); |
2017 | lpfc_cleanup(vport); | ||
2018 | |||
2019 | kthread_stop(phba->worker_thread); | ||
2020 | 2216 | ||
2021 | /* Release the irq reservation */ | 2217 | /* Release the irq reservation */ |
2022 | free_irq(phba->pcidev->irq, phba); | 2218 | free_irq(phba->pcidev->irq, phba); |
@@ -2048,7 +2244,7 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
2048 | 2244 | ||
2049 | kfree(phba); | 2245 | kfree(phba); |
2050 | 2246 | ||
2051 | pci_release_regions(pdev); | 2247 | pci_release_selected_regions(pdev, bars); |
2052 | pci_disable_device(pdev); | 2248 | pci_disable_device(pdev); |
2053 | } | 2249 | } |
2054 | 2250 | ||
@@ -2239,12 +2435,22 @@ lpfc_init(void) | |||
2239 | printk(LPFC_MODULE_DESC "\n"); | 2435 | printk(LPFC_MODULE_DESC "\n"); |
2240 | printk(LPFC_COPYRIGHT "\n"); | 2436 | printk(LPFC_COPYRIGHT "\n"); |
2241 | 2437 | ||
2438 | if (lpfc_enable_npiv) { | ||
2439 | lpfc_transport_functions.vport_create = lpfc_vport_create; | ||
2440 | lpfc_transport_functions.vport_delete = lpfc_vport_delete; | ||
2441 | } | ||
2242 | lpfc_transport_template = | 2442 | lpfc_transport_template = |
2243 | fc_attach_transport(&lpfc_transport_functions); | 2443 | fc_attach_transport(&lpfc_transport_functions); |
2244 | lpfc_vport_transport_template = | 2444 | if (lpfc_transport_template == NULL) |
2245 | fc_attach_transport(&lpfc_vport_transport_functions); | ||
2246 | if (!lpfc_transport_template || !lpfc_vport_transport_template) | ||
2247 | return -ENOMEM; | 2445 | return -ENOMEM; |
2446 | if (lpfc_enable_npiv) { | ||
2447 | lpfc_vport_transport_template = | ||
2448 | fc_attach_transport(&lpfc_vport_transport_functions); | ||
2449 | if (lpfc_vport_transport_template == NULL) { | ||
2450 | fc_release_transport(lpfc_transport_template); | ||
2451 | return -ENOMEM; | ||
2452 | } | ||
2453 | } | ||
2248 | error = pci_register_driver(&lpfc_driver); | 2454 | error = pci_register_driver(&lpfc_driver); |
2249 | if (error) { | 2455 | if (error) { |
2250 | fc_release_transport(lpfc_transport_template); | 2456 | fc_release_transport(lpfc_transport_template); |
@@ -2259,7 +2465,8 @@ lpfc_exit(void) | |||
2259 | { | 2465 | { |
2260 | pci_unregister_driver(&lpfc_driver); | 2466 | pci_unregister_driver(&lpfc_driver); |
2261 | fc_release_transport(lpfc_transport_template); | 2467 | fc_release_transport(lpfc_transport_template); |
2262 | fc_release_transport(lpfc_vport_transport_template); | 2468 | if (lpfc_enable_npiv) |
2469 | fc_release_transport(lpfc_vport_transport_template); | ||
2263 | } | 2470 | } |
2264 | 2471 | ||
2265 | module_init(lpfc_init); | 2472 | module_init(lpfc_init); |
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h index 626e4d878725..c5841d7565f7 100644 --- a/drivers/scsi/lpfc/lpfc_logmsg.h +++ b/drivers/scsi/lpfc/lpfc_logmsg.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #define LOG_IP 0x20 /* IP traffic history */ | 26 | #define LOG_IP 0x20 /* IP traffic history */ |
27 | #define LOG_FCP 0x40 /* FCP traffic history */ | 27 | #define LOG_FCP 0x40 /* FCP traffic history */ |
28 | #define LOG_NODE 0x80 /* Node table events */ | 28 | #define LOG_NODE 0x80 /* Node table events */ |
29 | #define LOG_TEMP 0x100 /* Temperature sensor events */ | ||
29 | #define LOG_MISC 0x400 /* Miscellaneous events */ | 30 | #define LOG_MISC 0x400 /* Miscellaneous events */ |
30 | #define LOG_SLI 0x800 /* SLI events */ | 31 | #define LOG_SLI 0x800 /* SLI events */ |
31 | #define LOG_FCP_ERROR 0x1000 /* log errors, not underruns */ | 32 | #define LOG_FCP_ERROR 0x1000 /* log errors, not underruns */ |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index a592733664e9..dfc63f6ccd7b 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -82,6 +82,24 @@ lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
82 | } | 82 | } |
83 | 83 | ||
84 | /**********************************************/ | 84 | /**********************************************/ |
85 | /* lpfc_config_async Issue a */ | ||
86 | /* MBX_ASYNC_EVT_ENABLE mailbox command */ | ||
87 | /**********************************************/ | ||
88 | void | ||
89 | lpfc_config_async(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, | ||
90 | uint32_t ring) | ||
91 | { | ||
92 | MAILBOX_t *mb; | ||
93 | |||
94 | mb = &pmb->mb; | ||
95 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | ||
96 | mb->mbxCommand = MBX_ASYNCEVT_ENABLE; | ||
97 | mb->un.varCfgAsyncEvent.ring = ring; | ||
98 | mb->mbxOwner = OWN_HOST; | ||
99 | return; | ||
100 | } | ||
101 | |||
102 | /**********************************************/ | ||
85 | /* lpfc_heart_beat Issue a HEART_BEAT */ | 103 | /* lpfc_heart_beat Issue a HEART_BEAT */ |
86 | /* mailbox command */ | 104 | /* mailbox command */ |
87 | /**********************************************/ | 105 | /**********************************************/ |
@@ -270,8 +288,10 @@ lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi) | |||
270 | 288 | ||
271 | /* Get a buffer to hold the HBAs Service Parameters */ | 289 | /* Get a buffer to hold the HBAs Service Parameters */ |
272 | 290 | ||
273 | if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) || | 291 | mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); |
274 | ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) { | 292 | if (mp) |
293 | mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); | ||
294 | if (!mp || !mp->virt) { | ||
275 | kfree(mp); | 295 | kfree(mp); |
276 | mb->mbxCommand = MBX_READ_SPARM64; | 296 | mb->mbxCommand = MBX_READ_SPARM64; |
277 | /* READ_SPARAM: no buffers */ | 297 | /* READ_SPARAM: no buffers */ |
@@ -369,8 +389,10 @@ lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, | |||
369 | mb->mbxOwner = OWN_HOST; | 389 | mb->mbxOwner = OWN_HOST; |
370 | 390 | ||
371 | /* Get a buffer to hold NPorts Service Parameters */ | 391 | /* Get a buffer to hold NPorts Service Parameters */ |
372 | if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == NULL) || | 392 | mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); |
373 | ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) { | 393 | if (mp) |
394 | mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); | ||
395 | if (!mp || !mp->virt) { | ||
374 | kfree(mp); | 396 | kfree(mp); |
375 | mb->mbxCommand = MBX_REG_LOGIN64; | 397 | mb->mbxCommand = MBX_REG_LOGIN64; |
376 | /* REG_LOGIN: no buffers */ | 398 | /* REG_LOGIN: no buffers */ |
@@ -874,7 +896,7 @@ lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) | |||
874 | case MBX_DOWN_LOAD: /* 0x1C */ | 896 | case MBX_DOWN_LOAD: /* 0x1C */ |
875 | case MBX_DEL_LD_ENTRY: /* 0x1D */ | 897 | case MBX_DEL_LD_ENTRY: /* 0x1D */ |
876 | case MBX_LOAD_AREA: /* 0x81 */ | 898 | case MBX_LOAD_AREA: /* 0x81 */ |
877 | case MBX_FLASH_WR_ULA: /* 0x98 */ | 899 | case MBX_WRITE_WWN: /* 0x98 */ |
878 | case MBX_LOAD_EXP_ROM: /* 0x9C */ | 900 | case MBX_LOAD_EXP_ROM: /* 0x9C */ |
879 | return LPFC_MBOX_TMO_FLASH_CMD; | 901 | return LPFC_MBOX_TMO_FLASH_CMD; |
880 | } | 902 | } |
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 43c3b8a0d76a..6dc5ab8d6716 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
@@ -98,6 +98,7 @@ lpfc_mem_alloc(struct lpfc_hba * phba) | |||
98 | 98 | ||
99 | fail_free_hbq_pool: | 99 | fail_free_hbq_pool: |
100 | lpfc_sli_hbqbuf_free_all(phba); | 100 | lpfc_sli_hbqbuf_free_all(phba); |
101 | pci_pool_destroy(phba->lpfc_hbq_pool); | ||
101 | fail_free_nlp_mem_pool: | 102 | fail_free_nlp_mem_pool: |
102 | mempool_destroy(phba->nlp_mem_pool); | 103 | mempool_destroy(phba->nlp_mem_pool); |
103 | phba->nlp_mem_pool = NULL; | 104 | phba->nlp_mem_pool = NULL; |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 880af0cd463d..4a0e3406e37a 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -287,6 +287,24 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
287 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 287 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
288 | lp = (uint32_t *) pcmd->virt; | 288 | lp = (uint32_t *) pcmd->virt; |
289 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 289 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
290 | if (wwn_to_u64(sp->portName.u.wwn) == 0) { | ||
291 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
292 | "0140 PLOGI Reject: invalid nname\n"); | ||
293 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | ||
294 | stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_PNAME; | ||
295 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, | ||
296 | NULL); | ||
297 | return 0; | ||
298 | } | ||
299 | if (wwn_to_u64(sp->nodeName.u.wwn) == 0) { | ||
300 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
301 | "0141 PLOGI Reject: invalid pname\n"); | ||
302 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | ||
303 | stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_NNAME; | ||
304 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, | ||
305 | NULL); | ||
306 | return 0; | ||
307 | } | ||
290 | if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3) == 0)) { | 308 | if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3) == 0)) { |
291 | /* Reject this request because invalid parameters */ | 309 | /* Reject this request because invalid parameters */ |
292 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 310 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
@@ -343,8 +361,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
343 | lpfc_config_link(phba, mbox); | 361 | lpfc_config_link(phba, mbox); |
344 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 362 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
345 | mbox->vport = vport; | 363 | mbox->vport = vport; |
346 | rc = lpfc_sli_issue_mbox | 364 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
347 | (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); | ||
348 | if (rc == MBX_NOT_FINISHED) { | 365 | if (rc == MBX_NOT_FINISHED) { |
349 | mempool_free(mbox, phba->mbox_mem_pool); | 366 | mempool_free(mbox, phba->mbox_mem_pool); |
350 | goto out; | 367 | goto out; |
@@ -407,6 +424,61 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
407 | ndlp, mbox); | 424 | ndlp, mbox); |
408 | return 1; | 425 | return 1; |
409 | } | 426 | } |
427 | |||
428 | /* If the remote NPort logs into us, before we can initiate | ||
429 | * discovery to them, cleanup the NPort from discovery accordingly. | ||
430 | */ | ||
431 | if (ndlp->nlp_state == NLP_STE_NPR_NODE) { | ||
432 | spin_lock_irq(shost->host_lock); | ||
433 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | ||
434 | spin_unlock_irq(shost->host_lock); | ||
435 | del_timer_sync(&ndlp->nlp_delayfunc); | ||
436 | ndlp->nlp_last_elscmd = 0; | ||
437 | |||
438 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | ||
439 | list_del_init(&ndlp->els_retry_evt.evt_listp); | ||
440 | |||
441 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
442 | spin_lock_irq(shost->host_lock); | ||
443 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | ||
444 | spin_unlock_irq(shost->host_lock); | ||
445 | |||
446 | if ((ndlp->nlp_flag & NLP_ADISC_SND) && | ||
447 | (vport->num_disc_nodes)) { | ||
448 | /* Check to see if there are more | ||
449 | * ADISCs to be sent | ||
450 | */ | ||
451 | lpfc_more_adisc(vport); | ||
452 | |||
453 | if ((vport->num_disc_nodes == 0) && | ||
454 | (vport->fc_npr_cnt)) | ||
455 | lpfc_els_disc_plogi(vport); | ||
456 | |||
457 | if (vport->num_disc_nodes == 0) { | ||
458 | spin_lock_irq(shost->host_lock); | ||
459 | vport->fc_flag &= ~FC_NDISC_ACTIVE; | ||
460 | spin_unlock_irq(shost->host_lock); | ||
461 | lpfc_can_disctmo(vport); | ||
462 | lpfc_end_rscn(vport); | ||
463 | } | ||
464 | } | ||
465 | else if (vport->num_disc_nodes) { | ||
466 | /* Check to see if there are more | ||
467 | * PLOGIs to be sent | ||
468 | */ | ||
469 | lpfc_more_plogi(vport); | ||
470 | |||
471 | if (vport->num_disc_nodes == 0) { | ||
472 | spin_lock_irq(shost->host_lock); | ||
473 | vport->fc_flag &= ~FC_NDISC_ACTIVE; | ||
474 | spin_unlock_irq(shost->host_lock); | ||
475 | lpfc_can_disctmo(vport); | ||
476 | lpfc_end_rscn(vport); | ||
477 | } | ||
478 | } | ||
479 | } | ||
480 | } | ||
481 | |||
410 | lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox); | 482 | lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox); |
411 | return 1; | 483 | return 1; |
412 | 484 | ||
@@ -501,12 +573,9 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
501 | spin_unlock_irq(shost->host_lock); | 573 | spin_unlock_irq(shost->host_lock); |
502 | 574 | ||
503 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 575 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
504 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
505 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | ||
506 | } else { | ||
507 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
508 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); | ||
509 | } | 576 | } |
577 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
578 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | ||
510 | 579 | ||
511 | spin_lock_irq(shost->host_lock); | 580 | spin_lock_irq(shost->host_lock); |
512 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 581 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
@@ -594,6 +663,25 @@ lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
594 | return ndlp->nlp_state; | 663 | return ndlp->nlp_state; |
595 | } | 664 | } |
596 | 665 | ||
666 | static uint32_t | ||
667 | lpfc_cmpl_plogi_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | ||
668 | void *arg, uint32_t evt) | ||
669 | { | ||
670 | /* This transition is only legal if we previously | ||
671 | * rcv'ed a PLOGI. Since we don't want 2 discovery threads | ||
672 | * working on the same NPortID, do nothing for this thread | ||
673 | * to stop it. | ||
674 | */ | ||
675 | if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) { | ||
676 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | ||
677 | "0253 Illegal State Transition: node x%x " | ||
678 | "event x%x, state x%x Data: x%x x%x\n", | ||
679 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, | ||
680 | ndlp->nlp_flag); | ||
681 | } | ||
682 | return ndlp->nlp_state; | ||
683 | } | ||
684 | |||
597 | /* Start of Discovery State Machine routines */ | 685 | /* Start of Discovery State Machine routines */ |
598 | 686 | ||
599 | static uint32_t | 687 | static uint32_t |
@@ -605,11 +693,8 @@ lpfc_rcv_plogi_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
605 | cmdiocb = (struct lpfc_iocbq *) arg; | 693 | cmdiocb = (struct lpfc_iocbq *) arg; |
606 | 694 | ||
607 | if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) { | 695 | if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) { |
608 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | ||
609 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); | ||
610 | return ndlp->nlp_state; | 696 | return ndlp->nlp_state; |
611 | } | 697 | } |
612 | lpfc_drop_node(vport, ndlp); | ||
613 | return NLP_STE_FREED_NODE; | 698 | return NLP_STE_FREED_NODE; |
614 | } | 699 | } |
615 | 700 | ||
@@ -618,7 +703,6 @@ lpfc_rcv_els_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
618 | void *arg, uint32_t evt) | 703 | void *arg, uint32_t evt) |
619 | { | 704 | { |
620 | lpfc_issue_els_logo(vport, ndlp, 0); | 705 | lpfc_issue_els_logo(vport, ndlp, 0); |
621 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); | ||
622 | return ndlp->nlp_state; | 706 | return ndlp->nlp_state; |
623 | } | 707 | } |
624 | 708 | ||
@@ -633,7 +717,6 @@ lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
633 | ndlp->nlp_flag |= NLP_LOGO_ACC; | 717 | ndlp->nlp_flag |= NLP_LOGO_ACC; |
634 | spin_unlock_irq(shost->host_lock); | 718 | spin_unlock_irq(shost->host_lock); |
635 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); | 719 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); |
636 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); | ||
637 | 720 | ||
638 | return ndlp->nlp_state; | 721 | return ndlp->nlp_state; |
639 | } | 722 | } |
@@ -642,7 +725,6 @@ static uint32_t | |||
642 | lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 725 | lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
643 | void *arg, uint32_t evt) | 726 | void *arg, uint32_t evt) |
644 | { | 727 | { |
645 | lpfc_drop_node(vport, ndlp); | ||
646 | return NLP_STE_FREED_NODE; | 728 | return NLP_STE_FREED_NODE; |
647 | } | 729 | } |
648 | 730 | ||
@@ -650,7 +732,6 @@ static uint32_t | |||
650 | lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 732 | lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
651 | void *arg, uint32_t evt) | 733 | void *arg, uint32_t evt) |
652 | { | 734 | { |
653 | lpfc_drop_node(vport, ndlp); | ||
654 | return NLP_STE_FREED_NODE; | 735 | return NLP_STE_FREED_NODE; |
655 | } | 736 | } |
656 | 737 | ||
@@ -752,6 +833,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, | |||
752 | uint32_t evt) | 833 | uint32_t evt) |
753 | { | 834 | { |
754 | struct lpfc_hba *phba = vport->phba; | 835 | struct lpfc_hba *phba = vport->phba; |
836 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
755 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 837 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
756 | struct lpfc_dmabuf *pcmd, *prsp, *mp; | 838 | struct lpfc_dmabuf *pcmd, *prsp, *mp; |
757 | uint32_t *lp; | 839 | uint32_t *lp; |
@@ -778,6 +860,12 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, | |||
778 | 860 | ||
779 | lp = (uint32_t *) prsp->virt; | 861 | lp = (uint32_t *) prsp->virt; |
780 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 862 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
863 | if (wwn_to_u64(sp->portName.u.wwn) == 0 || | ||
864 | wwn_to_u64(sp->nodeName.u.wwn) == 0) { | ||
865 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
866 | "0142 PLOGI RSP: Invalid WWN.\n"); | ||
867 | goto out; | ||
868 | } | ||
781 | if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3)) | 869 | if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3)) |
782 | goto out; | 870 | goto out; |
783 | /* PLOGI chkparm OK */ | 871 | /* PLOGI chkparm OK */ |
@@ -828,13 +916,15 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, | |||
828 | } | 916 | } |
829 | mbox->context2 = lpfc_nlp_get(ndlp); | 917 | mbox->context2 = lpfc_nlp_get(ndlp); |
830 | mbox->vport = vport; | 918 | mbox->vport = vport; |
831 | if (lpfc_sli_issue_mbox(phba, mbox, | 919 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) |
832 | (MBX_NOWAIT | MBX_STOP_IOCB)) | ||
833 | != MBX_NOT_FINISHED) { | 920 | != MBX_NOT_FINISHED) { |
834 | lpfc_nlp_set_state(vport, ndlp, | 921 | lpfc_nlp_set_state(vport, ndlp, |
835 | NLP_STE_REG_LOGIN_ISSUE); | 922 | NLP_STE_REG_LOGIN_ISSUE); |
836 | return ndlp->nlp_state; | 923 | return ndlp->nlp_state; |
837 | } | 924 | } |
925 | /* decrement node reference count to the failed mbox | ||
926 | * command | ||
927 | */ | ||
838 | lpfc_nlp_put(ndlp); | 928 | lpfc_nlp_put(ndlp); |
839 | mp = (struct lpfc_dmabuf *) mbox->context1; | 929 | mp = (struct lpfc_dmabuf *) mbox->context1; |
840 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 930 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
@@ -864,13 +954,27 @@ out: | |||
864 | "0261 Cannot Register NameServer login\n"); | 954 | "0261 Cannot Register NameServer login\n"); |
865 | } | 955 | } |
866 | 956 | ||
867 | /* Free this node since the driver cannot login or has the wrong | 957 | spin_lock_irq(shost->host_lock); |
868 | sparm */ | 958 | ndlp->nlp_flag |= NLP_DEFER_RM; |
869 | lpfc_drop_node(vport, ndlp); | 959 | spin_unlock_irq(shost->host_lock); |
870 | return NLP_STE_FREED_NODE; | 960 | return NLP_STE_FREED_NODE; |
871 | } | 961 | } |
872 | 962 | ||
873 | static uint32_t | 963 | static uint32_t |
964 | lpfc_cmpl_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | ||
965 | void *arg, uint32_t evt) | ||
966 | { | ||
967 | return ndlp->nlp_state; | ||
968 | } | ||
969 | |||
970 | static uint32_t | ||
971 | lpfc_cmpl_reglogin_plogi_issue(struct lpfc_vport *vport, | ||
972 | struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) | ||
973 | { | ||
974 | return ndlp->nlp_state; | ||
975 | } | ||
976 | |||
977 | static uint32_t | ||
874 | lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 978 | lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
875 | void *arg, uint32_t evt) | 979 | void *arg, uint32_t evt) |
876 | { | 980 | { |
@@ -1137,7 +1241,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport, | |||
1137 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 1241 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
1138 | mp = (struct lpfc_dmabuf *) (mb->context1); | 1242 | mp = (struct lpfc_dmabuf *) (mb->context1); |
1139 | if (mp) { | 1243 | if (mp) { |
1140 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1244 | __lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1141 | kfree(mp); | 1245 | kfree(mp); |
1142 | } | 1246 | } |
1143 | lpfc_nlp_put(ndlp); | 1247 | lpfc_nlp_put(ndlp); |
@@ -1197,8 +1301,8 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, | |||
1197 | * retry discovery. | 1301 | * retry discovery. |
1198 | */ | 1302 | */ |
1199 | if (mb->mbxStatus == MBXERR_RPI_FULL) { | 1303 | if (mb->mbxStatus == MBXERR_RPI_FULL) { |
1200 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | 1304 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1201 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); | 1305 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1202 | return ndlp->nlp_state; | 1306 | return ndlp->nlp_state; |
1203 | } | 1307 | } |
1204 | 1308 | ||
@@ -1378,7 +1482,7 @@ out: | |||
1378 | lpfc_issue_els_logo(vport, ndlp, 0); | 1482 | lpfc_issue_els_logo(vport, ndlp, 0); |
1379 | 1483 | ||
1380 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | 1484 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; |
1381 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); | 1485 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1382 | return ndlp->nlp_state; | 1486 | return ndlp->nlp_state; |
1383 | } | 1487 | } |
1384 | 1488 | ||
@@ -1753,7 +1857,7 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1753 | 1857 | ||
1754 | irsp = &rspiocb->iocb; | 1858 | irsp = &rspiocb->iocb; |
1755 | if (irsp->ulpStatus) { | 1859 | if (irsp->ulpStatus) { |
1756 | lpfc_drop_node(vport, ndlp); | 1860 | ndlp->nlp_flag |= NLP_DEFER_RM; |
1757 | return NLP_STE_FREED_NODE; | 1861 | return NLP_STE_FREED_NODE; |
1758 | } | 1862 | } |
1759 | return ndlp->nlp_state; | 1863 | return ndlp->nlp_state; |
@@ -1942,9 +2046,9 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | |||
1942 | lpfc_rcv_els_plogi_issue, /* RCV_PRLO */ | 2046 | lpfc_rcv_els_plogi_issue, /* RCV_PRLO */ |
1943 | lpfc_cmpl_plogi_plogi_issue, /* CMPL_PLOGI */ | 2047 | lpfc_cmpl_plogi_plogi_issue, /* CMPL_PLOGI */ |
1944 | lpfc_disc_illegal, /* CMPL_PRLI */ | 2048 | lpfc_disc_illegal, /* CMPL_PRLI */ |
1945 | lpfc_disc_illegal, /* CMPL_LOGO */ | 2049 | lpfc_cmpl_logo_plogi_issue, /* CMPL_LOGO */ |
1946 | lpfc_disc_illegal, /* CMPL_ADISC */ | 2050 | lpfc_disc_illegal, /* CMPL_ADISC */ |
1947 | lpfc_disc_illegal, /* CMPL_REG_LOGIN */ | 2051 | lpfc_cmpl_reglogin_plogi_issue,/* CMPL_REG_LOGIN */ |
1948 | lpfc_device_rm_plogi_issue, /* DEVICE_RM */ | 2052 | lpfc_device_rm_plogi_issue, /* DEVICE_RM */ |
1949 | lpfc_device_recov_plogi_issue, /* DEVICE_RECOVERY */ | 2053 | lpfc_device_recov_plogi_issue, /* DEVICE_RECOVERY */ |
1950 | 2054 | ||
@@ -1968,7 +2072,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | |||
1968 | lpfc_rcv_padisc_reglogin_issue, /* RCV_ADISC */ | 2072 | lpfc_rcv_padisc_reglogin_issue, /* RCV_ADISC */ |
1969 | lpfc_rcv_padisc_reglogin_issue, /* RCV_PDISC */ | 2073 | lpfc_rcv_padisc_reglogin_issue, /* RCV_PDISC */ |
1970 | lpfc_rcv_prlo_reglogin_issue, /* RCV_PRLO */ | 2074 | lpfc_rcv_prlo_reglogin_issue, /* RCV_PRLO */ |
1971 | lpfc_disc_illegal, /* CMPL_PLOGI */ | 2075 | lpfc_cmpl_plogi_illegal, /* CMPL_PLOGI */ |
1972 | lpfc_disc_illegal, /* CMPL_PRLI */ | 2076 | lpfc_disc_illegal, /* CMPL_PRLI */ |
1973 | lpfc_disc_illegal, /* CMPL_LOGO */ | 2077 | lpfc_disc_illegal, /* CMPL_LOGO */ |
1974 | lpfc_disc_illegal, /* CMPL_ADISC */ | 2078 | lpfc_disc_illegal, /* CMPL_ADISC */ |
@@ -1982,7 +2086,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | |||
1982 | lpfc_rcv_padisc_prli_issue, /* RCV_ADISC */ | 2086 | lpfc_rcv_padisc_prli_issue, /* RCV_ADISC */ |
1983 | lpfc_rcv_padisc_prli_issue, /* RCV_PDISC */ | 2087 | lpfc_rcv_padisc_prli_issue, /* RCV_PDISC */ |
1984 | lpfc_rcv_prlo_prli_issue, /* RCV_PRLO */ | 2088 | lpfc_rcv_prlo_prli_issue, /* RCV_PRLO */ |
1985 | lpfc_disc_illegal, /* CMPL_PLOGI */ | 2089 | lpfc_cmpl_plogi_illegal, /* CMPL_PLOGI */ |
1986 | lpfc_cmpl_prli_prli_issue, /* CMPL_PRLI */ | 2090 | lpfc_cmpl_prli_prli_issue, /* CMPL_PRLI */ |
1987 | lpfc_disc_illegal, /* CMPL_LOGO */ | 2091 | lpfc_disc_illegal, /* CMPL_LOGO */ |
1988 | lpfc_disc_illegal, /* CMPL_ADISC */ | 2092 | lpfc_disc_illegal, /* CMPL_ADISC */ |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 4e46045dea6d..6483c62730b3 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -130,7 +130,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) | |||
130 | 130 | ||
131 | vports = lpfc_create_vport_work_array(phba); | 131 | vports = lpfc_create_vport_work_array(phba); |
132 | if (vports != NULL) | 132 | if (vports != NULL) |
133 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 133 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
134 | shost = lpfc_shost_from_vport(vports[i]); | 134 | shost = lpfc_shost_from_vport(vports[i]); |
135 | shost_for_each_device(sdev, shost) { | 135 | shost_for_each_device(sdev, shost) { |
136 | new_queue_depth = | 136 | new_queue_depth = |
@@ -151,7 +151,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) | |||
151 | new_queue_depth); | 151 | new_queue_depth); |
152 | } | 152 | } |
153 | } | 153 | } |
154 | lpfc_destroy_vport_work_array(vports); | 154 | lpfc_destroy_vport_work_array(phba, vports); |
155 | atomic_set(&phba->num_rsrc_err, 0); | 155 | atomic_set(&phba->num_rsrc_err, 0); |
156 | atomic_set(&phba->num_cmd_success, 0); | 156 | atomic_set(&phba->num_cmd_success, 0); |
157 | } | 157 | } |
@@ -166,7 +166,7 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) | |||
166 | 166 | ||
167 | vports = lpfc_create_vport_work_array(phba); | 167 | vports = lpfc_create_vport_work_array(phba); |
168 | if (vports != NULL) | 168 | if (vports != NULL) |
169 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 169 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
170 | shost = lpfc_shost_from_vport(vports[i]); | 170 | shost = lpfc_shost_from_vport(vports[i]); |
171 | shost_for_each_device(sdev, shost) { | 171 | shost_for_each_device(sdev, shost) { |
172 | if (sdev->ordered_tags) | 172 | if (sdev->ordered_tags) |
@@ -179,7 +179,7 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) | |||
179 | sdev->queue_depth+1); | 179 | sdev->queue_depth+1); |
180 | } | 180 | } |
181 | } | 181 | } |
182 | lpfc_destroy_vport_work_array(vports); | 182 | lpfc_destroy_vport_work_array(phba, vports); |
183 | atomic_set(&phba->num_rsrc_err, 0); | 183 | atomic_set(&phba->num_rsrc_err, 0); |
184 | atomic_set(&phba->num_cmd_success, 0); | 184 | atomic_set(&phba->num_cmd_success, 0); |
185 | } | 185 | } |
@@ -380,7 +380,7 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
380 | (num_bde * sizeof (struct ulp_bde64)); | 380 | (num_bde * sizeof (struct ulp_bde64)); |
381 | iocb_cmd->ulpBdeCount = 1; | 381 | iocb_cmd->ulpBdeCount = 1; |
382 | iocb_cmd->ulpLe = 1; | 382 | iocb_cmd->ulpLe = 1; |
383 | fcp_cmnd->fcpDl = be32_to_cpu(scsi_bufflen(scsi_cmnd)); | 383 | fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); |
384 | return 0; | 384 | return 0; |
385 | } | 385 | } |
386 | 386 | ||
@@ -542,6 +542,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
542 | int result; | 542 | int result; |
543 | struct scsi_device *sdev, *tmp_sdev; | 543 | struct scsi_device *sdev, *tmp_sdev; |
544 | int depth = 0; | 544 | int depth = 0; |
545 | unsigned long flags; | ||
545 | 546 | ||
546 | lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; | 547 | lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; |
547 | lpfc_cmd->status = pIocbOut->iocb.ulpStatus; | 548 | lpfc_cmd->status = pIocbOut->iocb.ulpStatus; |
@@ -608,6 +609,15 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
608 | cmd->scsi_done(cmd); | 609 | cmd->scsi_done(cmd); |
609 | 610 | ||
610 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 611 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
612 | /* | ||
613 | * If there is a thread waiting for command completion | ||
614 | * wake up the thread. | ||
615 | */ | ||
616 | spin_lock_irqsave(sdev->host->host_lock, flags); | ||
617 | lpfc_cmd->pCmd = NULL; | ||
618 | if (lpfc_cmd->waitq) | ||
619 | wake_up(lpfc_cmd->waitq); | ||
620 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | ||
611 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 621 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
612 | return; | 622 | return; |
613 | } | 623 | } |
@@ -669,6 +679,16 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
669 | } | 679 | } |
670 | } | 680 | } |
671 | 681 | ||
682 | /* | ||
683 | * If there is a thread waiting for command completion | ||
684 | * wake up the thread. | ||
685 | */ | ||
686 | spin_lock_irqsave(sdev->host->host_lock, flags); | ||
687 | lpfc_cmd->pCmd = NULL; | ||
688 | if (lpfc_cmd->waitq) | ||
689 | wake_up(lpfc_cmd->waitq); | ||
690 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | ||
691 | |||
672 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 692 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
673 | } | 693 | } |
674 | 694 | ||
@@ -743,6 +763,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
743 | piocbq->iocb.ulpContext = pnode->nlp_rpi; | 763 | piocbq->iocb.ulpContext = pnode->nlp_rpi; |
744 | if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE) | 764 | if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE) |
745 | piocbq->iocb.ulpFCP2Rcvy = 1; | 765 | piocbq->iocb.ulpFCP2Rcvy = 1; |
766 | else | ||
767 | piocbq->iocb.ulpFCP2Rcvy = 0; | ||
746 | 768 | ||
747 | piocbq->iocb.ulpClass = (pnode->nlp_fcp_info & 0x0f); | 769 | piocbq->iocb.ulpClass = (pnode->nlp_fcp_info & 0x0f); |
748 | piocbq->context1 = lpfc_cmd; | 770 | piocbq->context1 = lpfc_cmd; |
@@ -1018,8 +1040,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
1018 | struct lpfc_iocbq *abtsiocb; | 1040 | struct lpfc_iocbq *abtsiocb; |
1019 | struct lpfc_scsi_buf *lpfc_cmd; | 1041 | struct lpfc_scsi_buf *lpfc_cmd; |
1020 | IOCB_t *cmd, *icmd; | 1042 | IOCB_t *cmd, *icmd; |
1021 | unsigned int loop_count = 0; | ||
1022 | int ret = SUCCESS; | 1043 | int ret = SUCCESS; |
1044 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); | ||
1023 | 1045 | ||
1024 | lpfc_block_error_handler(cmnd); | 1046 | lpfc_block_error_handler(cmnd); |
1025 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; | 1047 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
@@ -1074,17 +1096,15 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
1074 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) | 1096 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) |
1075 | lpfc_sli_poll_fcp_ring (phba); | 1097 | lpfc_sli_poll_fcp_ring (phba); |
1076 | 1098 | ||
1099 | lpfc_cmd->waitq = &waitq; | ||
1077 | /* Wait for abort to complete */ | 1100 | /* Wait for abort to complete */ |
1078 | while (lpfc_cmd->pCmd == cmnd) | 1101 | wait_event_timeout(waitq, |
1079 | { | 1102 | (lpfc_cmd->pCmd != cmnd), |
1080 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) | 1103 | (2*vport->cfg_devloss_tmo*HZ)); |
1081 | lpfc_sli_poll_fcp_ring (phba); | ||
1082 | 1104 | ||
1083 | schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ); | 1105 | spin_lock_irq(shost->host_lock); |
1084 | if (++loop_count | 1106 | lpfc_cmd->waitq = NULL; |
1085 | > (2 * vport->cfg_devloss_tmo)/LPFC_ABORT_WAIT) | 1107 | spin_unlock_irq(shost->host_lock); |
1086 | break; | ||
1087 | } | ||
1088 | 1108 | ||
1089 | if (lpfc_cmd->pCmd == cmnd) { | 1109 | if (lpfc_cmd->pCmd == cmnd) { |
1090 | ret = FAILED; | 1110 | ret = FAILED; |
@@ -1438,7 +1458,7 @@ struct scsi_host_template lpfc_template = { | |||
1438 | .slave_destroy = lpfc_slave_destroy, | 1458 | .slave_destroy = lpfc_slave_destroy, |
1439 | .scan_finished = lpfc_scan_finished, | 1459 | .scan_finished = lpfc_scan_finished, |
1440 | .this_id = -1, | 1460 | .this_id = -1, |
1441 | .sg_tablesize = LPFC_SG_SEG_CNT, | 1461 | .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, |
1442 | .use_sg_chaining = ENABLE_SG_CHAINING, | 1462 | .use_sg_chaining = ENABLE_SG_CHAINING, |
1443 | .cmd_per_lun = LPFC_CMD_PER_LUN, | 1463 | .cmd_per_lun = LPFC_CMD_PER_LUN, |
1444 | .use_clustering = ENABLE_CLUSTERING, | 1464 | .use_clustering = ENABLE_CLUSTERING, |
@@ -1459,7 +1479,7 @@ struct scsi_host_template lpfc_vport_template = { | |||
1459 | .slave_destroy = lpfc_slave_destroy, | 1479 | .slave_destroy = lpfc_slave_destroy, |
1460 | .scan_finished = lpfc_scan_finished, | 1480 | .scan_finished = lpfc_scan_finished, |
1461 | .this_id = -1, | 1481 | .this_id = -1, |
1462 | .sg_tablesize = LPFC_SG_SEG_CNT, | 1482 | .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, |
1463 | .cmd_per_lun = LPFC_CMD_PER_LUN, | 1483 | .cmd_per_lun = LPFC_CMD_PER_LUN, |
1464 | .use_clustering = ENABLE_CLUSTERING, | 1484 | .use_clustering = ENABLE_CLUSTERING, |
1465 | .use_sg_chaining = ENABLE_SG_CHAINING, | 1485 | .use_sg_chaining = ENABLE_SG_CHAINING, |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index 31787bb6d53e..daba92374985 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.h | |||
@@ -138,6 +138,7 @@ struct lpfc_scsi_buf { | |||
138 | * Iotag is in here | 138 | * Iotag is in here |
139 | */ | 139 | */ |
140 | struct lpfc_iocbq cur_iocbq; | 140 | struct lpfc_iocbq cur_iocbq; |
141 | wait_queue_head_t *waitq; | ||
141 | }; | 142 | }; |
142 | 143 | ||
143 | #define LPFC_SCSI_DMA_EXT_SIZE 264 | 144 | #define LPFC_SCSI_DMA_EXT_SIZE 264 |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index ce348c5c706c..fdd01e384e36 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -106,7 +106,7 @@ lpfc_sli_get_iocbq(struct lpfc_hba *phba) | |||
106 | return iocbq; | 106 | return iocbq; |
107 | } | 107 | } |
108 | 108 | ||
109 | void | 109 | static void |
110 | __lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) | 110 | __lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) |
111 | { | 111 | { |
112 | size_t start_clean = offsetof(struct lpfc_iocbq, iocb); | 112 | size_t start_clean = offsetof(struct lpfc_iocbq, iocb); |
@@ -199,6 +199,7 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) | |||
199 | case CMD_RCV_ELS_REQ_CX: | 199 | case CMD_RCV_ELS_REQ_CX: |
200 | case CMD_RCV_SEQUENCE64_CX: | 200 | case CMD_RCV_SEQUENCE64_CX: |
201 | case CMD_RCV_ELS_REQ64_CX: | 201 | case CMD_RCV_ELS_REQ64_CX: |
202 | case CMD_ASYNC_STATUS: | ||
202 | case CMD_IOCB_RCV_SEQ64_CX: | 203 | case CMD_IOCB_RCV_SEQ64_CX: |
203 | case CMD_IOCB_RCV_ELS64_CX: | 204 | case CMD_IOCB_RCV_ELS64_CX: |
204 | case CMD_IOCB_RCV_CONT64_CX: | 205 | case CMD_IOCB_RCV_CONT64_CX: |
@@ -473,8 +474,7 @@ lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
473 | if (pring->txq_cnt && | 474 | if (pring->txq_cnt && |
474 | lpfc_is_link_up(phba) && | 475 | lpfc_is_link_up(phba) && |
475 | (pring->ringno != phba->sli.fcp_ring || | 476 | (pring->ringno != phba->sli.fcp_ring || |
476 | phba->sli.sli_flag & LPFC_PROCESS_LA) && | 477 | phba->sli.sli_flag & LPFC_PROCESS_LA)) { |
477 | !(pring->flag & LPFC_STOP_IOCB_MBX)) { | ||
478 | 478 | ||
479 | while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) && | 479 | while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) && |
480 | (nextiocb = lpfc_sli_ringtx_get(phba, pring))) | 480 | (nextiocb = lpfc_sli_ringtx_get(phba, pring))) |
@@ -489,32 +489,7 @@ lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
489 | return; | 489 | return; |
490 | } | 490 | } |
491 | 491 | ||
492 | /* lpfc_sli_turn_on_ring is only called by lpfc_sli_handle_mb_event below */ | 492 | static struct lpfc_hbq_entry * |
493 | static void | ||
494 | lpfc_sli_turn_on_ring(struct lpfc_hba *phba, int ringno) | ||
495 | { | ||
496 | struct lpfc_pgp *pgp = (phba->sli_rev == 3) ? | ||
497 | &phba->slim2p->mbx.us.s3_pgp.port[ringno] : | ||
498 | &phba->slim2p->mbx.us.s2.port[ringno]; | ||
499 | unsigned long iflags; | ||
500 | |||
501 | /* If the ring is active, flag it */ | ||
502 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
503 | if (phba->sli.ring[ringno].cmdringaddr) { | ||
504 | if (phba->sli.ring[ringno].flag & LPFC_STOP_IOCB_MBX) { | ||
505 | phba->sli.ring[ringno].flag &= ~LPFC_STOP_IOCB_MBX; | ||
506 | /* | ||
507 | * Force update of the local copy of cmdGetInx | ||
508 | */ | ||
509 | phba->sli.ring[ringno].local_getidx | ||
510 | = le32_to_cpu(pgp->cmdGetInx); | ||
511 | lpfc_sli_resume_iocb(phba, &phba->sli.ring[ringno]); | ||
512 | } | ||
513 | } | ||
514 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
515 | } | ||
516 | |||
517 | struct lpfc_hbq_entry * | ||
518 | lpfc_sli_next_hbq_slot(struct lpfc_hba *phba, uint32_t hbqno) | 493 | lpfc_sli_next_hbq_slot(struct lpfc_hba *phba, uint32_t hbqno) |
519 | { | 494 | { |
520 | struct hbq_s *hbqp = &phba->hbqs[hbqno]; | 495 | struct hbq_s *hbqp = &phba->hbqs[hbqno]; |
@@ -565,6 +540,7 @@ lpfc_sli_hbqbuf_free_all(struct lpfc_hba *phba) | |||
565 | list_del(&hbq_buf->dbuf.list); | 540 | list_del(&hbq_buf->dbuf.list); |
566 | (phba->hbqs[i].hbq_free_buffer)(phba, hbq_buf); | 541 | (phba->hbqs[i].hbq_free_buffer)(phba, hbq_buf); |
567 | } | 542 | } |
543 | phba->hbqs[i].buffer_count = 0; | ||
568 | } | 544 | } |
569 | } | 545 | } |
570 | 546 | ||
@@ -633,8 +609,8 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) | |||
633 | return 0; | 609 | return 0; |
634 | } | 610 | } |
635 | 611 | ||
636 | start = lpfc_hbq_defs[hbqno]->buffer_count; | 612 | start = phba->hbqs[hbqno].buffer_count; |
637 | end = count + lpfc_hbq_defs[hbqno]->buffer_count; | 613 | end = count + start; |
638 | if (end > lpfc_hbq_defs[hbqno]->entry_count) { | 614 | if (end > lpfc_hbq_defs[hbqno]->entry_count) { |
639 | end = lpfc_hbq_defs[hbqno]->entry_count; | 615 | end = lpfc_hbq_defs[hbqno]->entry_count; |
640 | } | 616 | } |
@@ -646,7 +622,7 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) | |||
646 | return 1; | 622 | return 1; |
647 | hbq_buffer->tag = (i | (hbqno << 16)); | 623 | hbq_buffer->tag = (i | (hbqno << 16)); |
648 | if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) | 624 | if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) |
649 | lpfc_hbq_defs[hbqno]->buffer_count++; | 625 | phba->hbqs[hbqno].buffer_count++; |
650 | else | 626 | else |
651 | (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); | 627 | (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); |
652 | } | 628 | } |
@@ -660,14 +636,14 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) | |||
660 | lpfc_hbq_defs[qno]->add_count)); | 636 | lpfc_hbq_defs[qno]->add_count)); |
661 | } | 637 | } |
662 | 638 | ||
663 | int | 639 | static int |
664 | lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) | 640 | lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) |
665 | { | 641 | { |
666 | return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | 642 | return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, |
667 | lpfc_hbq_defs[qno]->init_count)); | 643 | lpfc_hbq_defs[qno]->init_count)); |
668 | } | 644 | } |
669 | 645 | ||
670 | struct hbq_dmabuf * | 646 | static struct hbq_dmabuf * |
671 | lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) | 647 | lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) |
672 | { | 648 | { |
673 | struct lpfc_dmabuf *d_buf; | 649 | struct lpfc_dmabuf *d_buf; |
@@ -686,7 +662,7 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) | |||
686 | } | 662 | } |
687 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT, | 663 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT, |
688 | "1803 Bad hbq tag. Data: x%x x%x\n", | 664 | "1803 Bad hbq tag. Data: x%x x%x\n", |
689 | tag, lpfc_hbq_defs[tag >> 16]->buffer_count); | 665 | tag, phba->hbqs[tag >> 16].buffer_count); |
690 | return NULL; | 666 | return NULL; |
691 | } | 667 | } |
692 | 668 | ||
@@ -712,6 +688,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
712 | case MBX_LOAD_SM: | 688 | case MBX_LOAD_SM: |
713 | case MBX_READ_NV: | 689 | case MBX_READ_NV: |
714 | case MBX_WRITE_NV: | 690 | case MBX_WRITE_NV: |
691 | case MBX_WRITE_VPARMS: | ||
715 | case MBX_RUN_BIU_DIAG: | 692 | case MBX_RUN_BIU_DIAG: |
716 | case MBX_INIT_LINK: | 693 | case MBX_INIT_LINK: |
717 | case MBX_DOWN_LINK: | 694 | case MBX_DOWN_LINK: |
@@ -739,7 +716,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
739 | case MBX_DEL_LD_ENTRY: | 716 | case MBX_DEL_LD_ENTRY: |
740 | case MBX_RUN_PROGRAM: | 717 | case MBX_RUN_PROGRAM: |
741 | case MBX_SET_MASK: | 718 | case MBX_SET_MASK: |
742 | case MBX_SET_SLIM: | 719 | case MBX_SET_VARIABLE: |
743 | case MBX_UNREG_D_ID: | 720 | case MBX_UNREG_D_ID: |
744 | case MBX_KILL_BOARD: | 721 | case MBX_KILL_BOARD: |
745 | case MBX_CONFIG_FARP: | 722 | case MBX_CONFIG_FARP: |
@@ -751,9 +728,10 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
751 | case MBX_READ_RPI64: | 728 | case MBX_READ_RPI64: |
752 | case MBX_REG_LOGIN64: | 729 | case MBX_REG_LOGIN64: |
753 | case MBX_READ_LA64: | 730 | case MBX_READ_LA64: |
754 | case MBX_FLASH_WR_ULA: | 731 | case MBX_WRITE_WWN: |
755 | case MBX_SET_DEBUG: | 732 | case MBX_SET_DEBUG: |
756 | case MBX_LOAD_EXP_ROM: | 733 | case MBX_LOAD_EXP_ROM: |
734 | case MBX_ASYNCEVT_ENABLE: | ||
757 | case MBX_REG_VPI: | 735 | case MBX_REG_VPI: |
758 | case MBX_UNREG_VPI: | 736 | case MBX_UNREG_VPI: |
759 | case MBX_HEARTBEAT: | 737 | case MBX_HEARTBEAT: |
@@ -953,6 +931,17 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) | |||
953 | return &new_hbq_entry->dbuf; | 931 | return &new_hbq_entry->dbuf; |
954 | } | 932 | } |
955 | 933 | ||
934 | static struct lpfc_dmabuf * | ||
935 | lpfc_sli_get_buff(struct lpfc_hba *phba, | ||
936 | struct lpfc_sli_ring *pring, | ||
937 | uint32_t tag) | ||
938 | { | ||
939 | if (tag & QUE_BUFTAG_BIT) | ||
940 | return lpfc_sli_ring_taggedbuf_get(phba, pring, tag); | ||
941 | else | ||
942 | return lpfc_sli_replace_hbqbuff(phba, tag); | ||
943 | } | ||
944 | |||
956 | static int | 945 | static int |
957 | lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 946 | lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
958 | struct lpfc_iocbq *saveq) | 947 | struct lpfc_iocbq *saveq) |
@@ -961,19 +950,112 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
961 | WORD5 * w5p; | 950 | WORD5 * w5p; |
962 | uint32_t Rctl, Type; | 951 | uint32_t Rctl, Type; |
963 | uint32_t match, i; | 952 | uint32_t match, i; |
953 | struct lpfc_iocbq *iocbq; | ||
964 | 954 | ||
965 | match = 0; | 955 | match = 0; |
966 | irsp = &(saveq->iocb); | 956 | irsp = &(saveq->iocb); |
967 | if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX) | 957 | |
968 | || (irsp->ulpCommand == CMD_RCV_ELS_REQ_CX) | 958 | if (irsp->ulpStatus == IOSTAT_NEED_BUFFER) |
969 | || (irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX) | 959 | return 1; |
970 | || (irsp->ulpCommand == CMD_IOCB_RCV_CONT64_CX)) { | 960 | if (irsp->ulpCommand == CMD_ASYNC_STATUS) { |
961 | if (pring->lpfc_sli_rcv_async_status) | ||
962 | pring->lpfc_sli_rcv_async_status(phba, pring, saveq); | ||
963 | else | ||
964 | lpfc_printf_log(phba, | ||
965 | KERN_WARNING, | ||
966 | LOG_SLI, | ||
967 | "0316 Ring %d handler: unexpected " | ||
968 | "ASYNC_STATUS iocb received evt_code " | ||
969 | "0x%x\n", | ||
970 | pring->ringno, | ||
971 | irsp->un.asyncstat.evt_code); | ||
972 | return 1; | ||
973 | } | ||
974 | |||
975 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | ||
976 | if (irsp->ulpBdeCount != 0) { | ||
977 | saveq->context2 = lpfc_sli_get_buff(phba, pring, | ||
978 | irsp->un.ulpWord[3]); | ||
979 | if (!saveq->context2) | ||
980 | lpfc_printf_log(phba, | ||
981 | KERN_ERR, | ||
982 | LOG_SLI, | ||
983 | "0341 Ring %d Cannot find buffer for " | ||
984 | "an unsolicited iocb. tag 0x%x\n", | ||
985 | pring->ringno, | ||
986 | irsp->un.ulpWord[3]); | ||
987 | } | ||
988 | if (irsp->ulpBdeCount == 2) { | ||
989 | saveq->context3 = lpfc_sli_get_buff(phba, pring, | ||
990 | irsp->unsli3.sli3Words[7]); | ||
991 | if (!saveq->context3) | ||
992 | lpfc_printf_log(phba, | ||
993 | KERN_ERR, | ||
994 | LOG_SLI, | ||
995 | "0342 Ring %d Cannot find buffer for an" | ||
996 | " unsolicited iocb. tag 0x%x\n", | ||
997 | pring->ringno, | ||
998 | irsp->unsli3.sli3Words[7]); | ||
999 | } | ||
1000 | list_for_each_entry(iocbq, &saveq->list, list) { | ||
1001 | irsp = &(iocbq->iocb); | ||
1002 | if (irsp->ulpBdeCount != 0) { | ||
1003 | iocbq->context2 = lpfc_sli_get_buff(phba, pring, | ||
1004 | irsp->un.ulpWord[3]); | ||
1005 | if (!iocbq->context2) | ||
1006 | lpfc_printf_log(phba, | ||
1007 | KERN_ERR, | ||
1008 | LOG_SLI, | ||
1009 | "0343 Ring %d Cannot find " | ||
1010 | "buffer for an unsolicited iocb" | ||
1011 | ". tag 0x%x\n", pring->ringno, | ||
1012 | irsp->un.ulpWord[3]); | ||
1013 | } | ||
1014 | if (irsp->ulpBdeCount == 2) { | ||
1015 | iocbq->context3 = lpfc_sli_get_buff(phba, pring, | ||
1016 | irsp->unsli3.sli3Words[7]); | ||
1017 | if (!iocbq->context3) | ||
1018 | lpfc_printf_log(phba, | ||
1019 | KERN_ERR, | ||
1020 | LOG_SLI, | ||
1021 | "0344 Ring %d Cannot find " | ||
1022 | "buffer for an unsolicited " | ||
1023 | "iocb. tag 0x%x\n", | ||
1024 | pring->ringno, | ||
1025 | irsp->unsli3.sli3Words[7]); | ||
1026 | } | ||
1027 | } | ||
1028 | } | ||
1029 | if (irsp->ulpBdeCount != 0 && | ||
1030 | (irsp->ulpCommand == CMD_IOCB_RCV_CONT64_CX || | ||
1031 | irsp->ulpStatus == IOSTAT_INTERMED_RSP)) { | ||
1032 | int found = 0; | ||
1033 | |||
1034 | /* search continue save q for same XRI */ | ||
1035 | list_for_each_entry(iocbq, &pring->iocb_continue_saveq, clist) { | ||
1036 | if (iocbq->iocb.ulpContext == saveq->iocb.ulpContext) { | ||
1037 | list_add_tail(&saveq->list, &iocbq->list); | ||
1038 | found = 1; | ||
1039 | break; | ||
1040 | } | ||
1041 | } | ||
1042 | if (!found) | ||
1043 | list_add_tail(&saveq->clist, | ||
1044 | &pring->iocb_continue_saveq); | ||
1045 | if (saveq->iocb.ulpStatus != IOSTAT_INTERMED_RSP) { | ||
1046 | list_del_init(&iocbq->clist); | ||
1047 | saveq = iocbq; | ||
1048 | irsp = &(saveq->iocb); | ||
1049 | } else | ||
1050 | return 0; | ||
1051 | } | ||
1052 | if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX) || | ||
1053 | (irsp->ulpCommand == CMD_RCV_ELS_REQ_CX) || | ||
1054 | (irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX)) { | ||
971 | Rctl = FC_ELS_REQ; | 1055 | Rctl = FC_ELS_REQ; |
972 | Type = FC_ELS_DATA; | 1056 | Type = FC_ELS_DATA; |
973 | } else { | 1057 | } else { |
974 | w5p = | 1058 | w5p = (WORD5 *)&(saveq->iocb.un.ulpWord[5]); |
975 | (WORD5 *) & (saveq->iocb.un. | ||
976 | ulpWord[5]); | ||
977 | Rctl = w5p->hcsw.Rctl; | 1059 | Rctl = w5p->hcsw.Rctl; |
978 | Type = w5p->hcsw.Type; | 1060 | Type = w5p->hcsw.Type; |
979 | 1061 | ||
@@ -988,15 +1070,6 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
988 | } | 1070 | } |
989 | } | 1071 | } |
990 | 1072 | ||
991 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | ||
992 | if (irsp->ulpBdeCount != 0) | ||
993 | saveq->context2 = lpfc_sli_replace_hbqbuff(phba, | ||
994 | irsp->un.ulpWord[3]); | ||
995 | if (irsp->ulpBdeCount == 2) | ||
996 | saveq->context3 = lpfc_sli_replace_hbqbuff(phba, | ||
997 | irsp->unsli3.sli3Words[7]); | ||
998 | } | ||
999 | |||
1000 | /* unSolicited Responses */ | 1073 | /* unSolicited Responses */ |
1001 | if (pring->prt[0].profile) { | 1074 | if (pring->prt[0].profile) { |
1002 | if (pring->prt[0].lpfc_sli_rcv_unsol_event) | 1075 | if (pring->prt[0].lpfc_sli_rcv_unsol_event) |
@@ -1006,12 +1079,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
1006 | } else { | 1079 | } else { |
1007 | /* We must search, based on rctl / type | 1080 | /* We must search, based on rctl / type |
1008 | for the right routine */ | 1081 | for the right routine */ |
1009 | for (i = 0; i < pring->num_mask; | 1082 | for (i = 0; i < pring->num_mask; i++) { |
1010 | i++) { | 1083 | if ((pring->prt[i].rctl == Rctl) |
1011 | if ((pring->prt[i].rctl == | 1084 | && (pring->prt[i].type == Type)) { |
1012 | Rctl) | ||
1013 | && (pring->prt[i]. | ||
1014 | type == Type)) { | ||
1015 | if (pring->prt[i].lpfc_sli_rcv_unsol_event) | 1085 | if (pring->prt[i].lpfc_sli_rcv_unsol_event) |
1016 | (pring->prt[i].lpfc_sli_rcv_unsol_event) | 1086 | (pring->prt[i].lpfc_sli_rcv_unsol_event) |
1017 | (phba, pring, saveq); | 1087 | (phba, pring, saveq); |
@@ -1084,6 +1154,12 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
1084 | IOSTAT_LOCAL_REJECT; | 1154 | IOSTAT_LOCAL_REJECT; |
1085 | saveq->iocb.un.ulpWord[4] = | 1155 | saveq->iocb.un.ulpWord[4] = |
1086 | IOERR_SLI_ABORTED; | 1156 | IOERR_SLI_ABORTED; |
1157 | |||
1158 | /* Firmware could still be in progress | ||
1159 | * of DMAing payload, so don't free data | ||
1160 | * buffer till after a hbeat. | ||
1161 | */ | ||
1162 | saveq->iocb_flag |= LPFC_DELAY_MEM_FREE; | ||
1087 | } | 1163 | } |
1088 | } | 1164 | } |
1089 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | 1165 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); |
@@ -1572,12 +1648,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, | |||
1572 | 1648 | ||
1573 | writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx); | 1649 | writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx); |
1574 | 1650 | ||
1575 | if (list_empty(&(pring->iocb_continueq))) { | 1651 | list_add_tail(&rspiocbp->list, &(pring->iocb_continueq)); |
1576 | list_add(&rspiocbp->list, &(pring->iocb_continueq)); | ||
1577 | } else { | ||
1578 | list_add_tail(&rspiocbp->list, | ||
1579 | &(pring->iocb_continueq)); | ||
1580 | } | ||
1581 | 1652 | ||
1582 | pring->iocb_continueq_cnt++; | 1653 | pring->iocb_continueq_cnt++; |
1583 | if (irsp->ulpLe) { | 1654 | if (irsp->ulpLe) { |
@@ -1642,17 +1713,17 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, | |||
1642 | iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK; | 1713 | iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK; |
1643 | type = lpfc_sli_iocb_cmd_type(iocb_cmd_type); | 1714 | type = lpfc_sli_iocb_cmd_type(iocb_cmd_type); |
1644 | if (type == LPFC_SOL_IOCB) { | 1715 | if (type == LPFC_SOL_IOCB) { |
1645 | spin_unlock_irqrestore(&phba->hbalock, | 1716 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1646 | iflag); | ||
1647 | rc = lpfc_sli_process_sol_iocb(phba, pring, | 1717 | rc = lpfc_sli_process_sol_iocb(phba, pring, |
1648 | saveq); | 1718 | saveq); |
1649 | spin_lock_irqsave(&phba->hbalock, iflag); | 1719 | spin_lock_irqsave(&phba->hbalock, iflag); |
1650 | } else if (type == LPFC_UNSOL_IOCB) { | 1720 | } else if (type == LPFC_UNSOL_IOCB) { |
1651 | spin_unlock_irqrestore(&phba->hbalock, | 1721 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1652 | iflag); | ||
1653 | rc = lpfc_sli_process_unsol_iocb(phba, pring, | 1722 | rc = lpfc_sli_process_unsol_iocb(phba, pring, |
1654 | saveq); | 1723 | saveq); |
1655 | spin_lock_irqsave(&phba->hbalock, iflag); | 1724 | spin_lock_irqsave(&phba->hbalock, iflag); |
1725 | if (!rc) | ||
1726 | free_saveq = 0; | ||
1656 | } else if (type == LPFC_ABORT_IOCB) { | 1727 | } else if (type == LPFC_ABORT_IOCB) { |
1657 | if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) && | 1728 | if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) && |
1658 | ((cmdiocbp = | 1729 | ((cmdiocbp = |
@@ -1921,8 +1992,8 @@ lpfc_sli_brdkill(struct lpfc_hba *phba) | |||
1921 | "0329 Kill HBA Data: x%x x%x\n", | 1992 | "0329 Kill HBA Data: x%x x%x\n", |
1922 | phba->pport->port_state, psli->sli_flag); | 1993 | phba->pport->port_state, psli->sli_flag); |
1923 | 1994 | ||
1924 | if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, | 1995 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
1925 | GFP_KERNEL)) == 0) | 1996 | if (!pmb) |
1926 | return 1; | 1997 | return 1; |
1927 | 1998 | ||
1928 | /* Disable the error attention */ | 1999 | /* Disable the error attention */ |
@@ -2113,7 +2184,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2113 | <status> */ | 2184 | <status> */ |
2114 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2185 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2115 | "0436 Adapter failed to init, " | 2186 | "0436 Adapter failed to init, " |
2116 | "timeout, status reg x%x\n", status); | 2187 | "timeout, status reg x%x, " |
2188 | "FW Data: A8 x%x AC x%x\n", status, | ||
2189 | readl(phba->MBslimaddr + 0xa8), | ||
2190 | readl(phba->MBslimaddr + 0xac)); | ||
2117 | phba->link_state = LPFC_HBA_ERROR; | 2191 | phba->link_state = LPFC_HBA_ERROR; |
2118 | return -ETIMEDOUT; | 2192 | return -ETIMEDOUT; |
2119 | } | 2193 | } |
@@ -2125,7 +2199,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2125 | <status> */ | 2199 | <status> */ |
2126 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2200 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2127 | "0437 Adapter failed to init, " | 2201 | "0437 Adapter failed to init, " |
2128 | "chipset, status reg x%x\n", status); | 2202 | "chipset, status reg x%x, " |
2203 | "FW Data: A8 x%x AC x%x\n", status, | ||
2204 | readl(phba->MBslimaddr + 0xa8), | ||
2205 | readl(phba->MBslimaddr + 0xac)); | ||
2129 | phba->link_state = LPFC_HBA_ERROR; | 2206 | phba->link_state = LPFC_HBA_ERROR; |
2130 | return -EIO; | 2207 | return -EIO; |
2131 | } | 2208 | } |
@@ -2153,7 +2230,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2153 | /* Adapter failed to init, chipset, status reg <status> */ | 2230 | /* Adapter failed to init, chipset, status reg <status> */ |
2154 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2231 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2155 | "0438 Adapter failed to init, chipset, " | 2232 | "0438 Adapter failed to init, chipset, " |
2156 | "status reg x%x\n", status); | 2233 | "status reg x%x, " |
2234 | "FW Data: A8 x%x AC x%x\n", status, | ||
2235 | readl(phba->MBslimaddr + 0xa8), | ||
2236 | readl(phba->MBslimaddr + 0xac)); | ||
2157 | phba->link_state = LPFC_HBA_ERROR; | 2237 | phba->link_state = LPFC_HBA_ERROR; |
2158 | return -EIO; | 2238 | return -EIO; |
2159 | } | 2239 | } |
@@ -2485,11 +2565,16 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2485 | lpfc_sli_abort_iocb_ring(phba, pring); | 2565 | lpfc_sli_abort_iocb_ring(phba, pring); |
2486 | 2566 | ||
2487 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 2567 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, |
2488 | "0316 Resetting board due to mailbox timeout\n"); | 2568 | "0345 Resetting board due to mailbox timeout\n"); |
2489 | /* | 2569 | /* |
2490 | * lpfc_offline calls lpfc_sli_hba_down which will clean up | 2570 | * lpfc_offline calls lpfc_sli_hba_down which will clean up |
2491 | * on oustanding mailbox commands. | 2571 | * on oustanding mailbox commands. |
2492 | */ | 2572 | */ |
2573 | /* If resets are disabled then set error state and return. */ | ||
2574 | if (!phba->cfg_enable_hba_reset) { | ||
2575 | phba->link_state = LPFC_HBA_ERROR; | ||
2576 | return; | ||
2577 | } | ||
2493 | lpfc_offline_prep(phba); | 2578 | lpfc_offline_prep(phba); |
2494 | lpfc_offline(phba); | 2579 | lpfc_offline(phba); |
2495 | lpfc_sli_brdrestart(phba); | 2580 | lpfc_sli_brdrestart(phba); |
@@ -2507,6 +2592,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2507 | uint32_t status, evtctr; | 2592 | uint32_t status, evtctr; |
2508 | uint32_t ha_copy; | 2593 | uint32_t ha_copy; |
2509 | int i; | 2594 | int i; |
2595 | unsigned long timeout; | ||
2510 | unsigned long drvr_flag = 0; | 2596 | unsigned long drvr_flag = 0; |
2511 | volatile uint32_t word0, ldata; | 2597 | volatile uint32_t word0, ldata; |
2512 | void __iomem *to_slim; | 2598 | void __iomem *to_slim; |
@@ -2519,7 +2605,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2519 | "1806 Mbox x%x failed. No vport\n", | 2605 | "1806 Mbox x%x failed. No vport\n", |
2520 | pmbox->mb.mbxCommand); | 2606 | pmbox->mb.mbxCommand); |
2521 | dump_stack(); | 2607 | dump_stack(); |
2522 | return MBXERR_ERROR; | 2608 | return MBX_NOT_FINISHED; |
2523 | } | 2609 | } |
2524 | } | 2610 | } |
2525 | 2611 | ||
@@ -2571,21 +2657,6 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2571 | return MBX_NOT_FINISHED; | 2657 | return MBX_NOT_FINISHED; |
2572 | } | 2658 | } |
2573 | 2659 | ||
2574 | /* Handle STOP IOCB processing flag. This is only meaningful | ||
2575 | * if we are not polling for mbox completion. | ||
2576 | */ | ||
2577 | if (flag & MBX_STOP_IOCB) { | ||
2578 | flag &= ~MBX_STOP_IOCB; | ||
2579 | /* Now flag each ring */ | ||
2580 | for (i = 0; i < psli->num_rings; i++) { | ||
2581 | /* If the ring is active, flag it */ | ||
2582 | if (psli->ring[i].cmdringaddr) { | ||
2583 | psli->ring[i].flag |= | ||
2584 | LPFC_STOP_IOCB_MBX; | ||
2585 | } | ||
2586 | } | ||
2587 | } | ||
2588 | |||
2589 | /* Another mailbox command is still being processed, queue this | 2660 | /* Another mailbox command is still being processed, queue this |
2590 | * command to be processed later. | 2661 | * command to be processed later. |
2591 | */ | 2662 | */ |
@@ -2620,23 +2691,6 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2620 | return MBX_BUSY; | 2691 | return MBX_BUSY; |
2621 | } | 2692 | } |
2622 | 2693 | ||
2623 | /* Handle STOP IOCB processing flag. This is only meaningful | ||
2624 | * if we are not polling for mbox completion. | ||
2625 | */ | ||
2626 | if (flag & MBX_STOP_IOCB) { | ||
2627 | flag &= ~MBX_STOP_IOCB; | ||
2628 | if (flag == MBX_NOWAIT) { | ||
2629 | /* Now flag each ring */ | ||
2630 | for (i = 0; i < psli->num_rings; i++) { | ||
2631 | /* If the ring is active, flag it */ | ||
2632 | if (psli->ring[i].cmdringaddr) { | ||
2633 | psli->ring[i].flag |= | ||
2634 | LPFC_STOP_IOCB_MBX; | ||
2635 | } | ||
2636 | } | ||
2637 | } | ||
2638 | } | ||
2639 | |||
2640 | psli->sli_flag |= LPFC_SLI_MBOX_ACTIVE; | 2694 | psli->sli_flag |= LPFC_SLI_MBOX_ACTIVE; |
2641 | 2695 | ||
2642 | /* If we are not polling, we MUST be in SLI2 mode */ | 2696 | /* If we are not polling, we MUST be in SLI2 mode */ |
@@ -2714,18 +2768,24 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2714 | } | 2768 | } |
2715 | 2769 | ||
2716 | wmb(); | 2770 | wmb(); |
2717 | /* interrupt board to doit right away */ | ||
2718 | writel(CA_MBATT, phba->CAregaddr); | ||
2719 | readl(phba->CAregaddr); /* flush */ | ||
2720 | 2771 | ||
2721 | switch (flag) { | 2772 | switch (flag) { |
2722 | case MBX_NOWAIT: | 2773 | case MBX_NOWAIT: |
2723 | /* Don't wait for it to finish, just return */ | 2774 | /* Set up reference to mailbox command */ |
2724 | psli->mbox_active = pmbox; | 2775 | psli->mbox_active = pmbox; |
2776 | /* Interrupt board to do it */ | ||
2777 | writel(CA_MBATT, phba->CAregaddr); | ||
2778 | readl(phba->CAregaddr); /* flush */ | ||
2779 | /* Don't wait for it to finish, just return */ | ||
2725 | break; | 2780 | break; |
2726 | 2781 | ||
2727 | case MBX_POLL: | 2782 | case MBX_POLL: |
2783 | /* Set up null reference to mailbox command */ | ||
2728 | psli->mbox_active = NULL; | 2784 | psli->mbox_active = NULL; |
2785 | /* Interrupt board to do it */ | ||
2786 | writel(CA_MBATT, phba->CAregaddr); | ||
2787 | readl(phba->CAregaddr); /* flush */ | ||
2788 | |||
2729 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { | 2789 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { |
2730 | /* First read mbox status word */ | 2790 | /* First read mbox status word */ |
2731 | word0 = *((volatile uint32_t *)&phba->slim2p->mbx); | 2791 | word0 = *((volatile uint32_t *)&phba->slim2p->mbx); |
@@ -2737,15 +2797,15 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2737 | 2797 | ||
2738 | /* Read the HBA Host Attention Register */ | 2798 | /* Read the HBA Host Attention Register */ |
2739 | ha_copy = readl(phba->HAregaddr); | 2799 | ha_copy = readl(phba->HAregaddr); |
2740 | 2800 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, | |
2741 | i = lpfc_mbox_tmo_val(phba, mb->mbxCommand); | 2801 | mb->mbxCommand) * |
2742 | i *= 1000; /* Convert to ms */ | 2802 | 1000) + jiffies; |
2743 | 2803 | i = 0; | |
2744 | /* Wait for command to complete */ | 2804 | /* Wait for command to complete */ |
2745 | while (((word0 & OWN_CHIP) == OWN_CHIP) || | 2805 | while (((word0 & OWN_CHIP) == OWN_CHIP) || |
2746 | (!(ha_copy & HA_MBATT) && | 2806 | (!(ha_copy & HA_MBATT) && |
2747 | (phba->link_state > LPFC_WARM_START))) { | 2807 | (phba->link_state > LPFC_WARM_START))) { |
2748 | if (i-- <= 0) { | 2808 | if (time_after(jiffies, timeout)) { |
2749 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2809 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2750 | spin_unlock_irqrestore(&phba->hbalock, | 2810 | spin_unlock_irqrestore(&phba->hbalock, |
2751 | drvr_flag); | 2811 | drvr_flag); |
@@ -2758,12 +2818,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2758 | && (evtctr != psli->slistat.mbox_event)) | 2818 | && (evtctr != psli->slistat.mbox_event)) |
2759 | break; | 2819 | break; |
2760 | 2820 | ||
2761 | spin_unlock_irqrestore(&phba->hbalock, | 2821 | if (i++ > 10) { |
2762 | drvr_flag); | 2822 | spin_unlock_irqrestore(&phba->hbalock, |
2763 | 2823 | drvr_flag); | |
2764 | msleep(1); | 2824 | msleep(1); |
2765 | 2825 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | |
2766 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | 2826 | } |
2767 | 2827 | ||
2768 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { | 2828 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { |
2769 | /* First copy command data */ | 2829 | /* First copy command data */ |
@@ -2848,7 +2908,7 @@ lpfc_sli_next_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2848 | /* | 2908 | /* |
2849 | * Lockless version of lpfc_sli_issue_iocb. | 2909 | * Lockless version of lpfc_sli_issue_iocb. |
2850 | */ | 2910 | */ |
2851 | int | 2911 | static int |
2852 | __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 2912 | __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
2853 | struct lpfc_iocbq *piocb, uint32_t flag) | 2913 | struct lpfc_iocbq *piocb, uint32_t flag) |
2854 | { | 2914 | { |
@@ -2879,9 +2939,9 @@ __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2879 | 2939 | ||
2880 | /* | 2940 | /* |
2881 | * Check to see if we are blocking IOCB processing because of a | 2941 | * Check to see if we are blocking IOCB processing because of a |
2882 | * outstanding mbox command. | 2942 | * outstanding event. |
2883 | */ | 2943 | */ |
2884 | if (unlikely(pring->flag & LPFC_STOP_IOCB_MBX)) | 2944 | if (unlikely(pring->flag & LPFC_STOP_IOCB_EVENT)) |
2885 | goto iocb_busy; | 2945 | goto iocb_busy; |
2886 | 2946 | ||
2887 | if (unlikely(phba->link_state == LPFC_LINK_DOWN)) { | 2947 | if (unlikely(phba->link_state == LPFC_LINK_DOWN)) { |
@@ -2993,6 +3053,61 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba) | |||
2993 | return 0; | 3053 | return 0; |
2994 | } | 3054 | } |
2995 | 3055 | ||
3056 | static void | ||
3057 | lpfc_sli_async_event_handler(struct lpfc_hba * phba, | ||
3058 | struct lpfc_sli_ring * pring, struct lpfc_iocbq * iocbq) | ||
3059 | { | ||
3060 | IOCB_t *icmd; | ||
3061 | uint16_t evt_code; | ||
3062 | uint16_t temp; | ||
3063 | struct temp_event temp_event_data; | ||
3064 | struct Scsi_Host *shost; | ||
3065 | |||
3066 | icmd = &iocbq->iocb; | ||
3067 | evt_code = icmd->un.asyncstat.evt_code; | ||
3068 | temp = icmd->ulpContext; | ||
3069 | |||
3070 | if ((evt_code != ASYNC_TEMP_WARN) && | ||
3071 | (evt_code != ASYNC_TEMP_SAFE)) { | ||
3072 | lpfc_printf_log(phba, | ||
3073 | KERN_ERR, | ||
3074 | LOG_SLI, | ||
3075 | "0346 Ring %d handler: unexpected ASYNC_STATUS" | ||
3076 | " evt_code 0x%x\n", | ||
3077 | pring->ringno, | ||
3078 | icmd->un.asyncstat.evt_code); | ||
3079 | return; | ||
3080 | } | ||
3081 | temp_event_data.data = (uint32_t)temp; | ||
3082 | temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT; | ||
3083 | if (evt_code == ASYNC_TEMP_WARN) { | ||
3084 | temp_event_data.event_code = LPFC_THRESHOLD_TEMP; | ||
3085 | lpfc_printf_log(phba, | ||
3086 | KERN_ERR, | ||
3087 | LOG_TEMP, | ||
3088 | "0347 Adapter is very hot, please take " | ||
3089 | "corrective action. temperature : %d Celsius\n", | ||
3090 | temp); | ||
3091 | } | ||
3092 | if (evt_code == ASYNC_TEMP_SAFE) { | ||
3093 | temp_event_data.event_code = LPFC_NORMAL_TEMP; | ||
3094 | lpfc_printf_log(phba, | ||
3095 | KERN_ERR, | ||
3096 | LOG_TEMP, | ||
3097 | "0340 Adapter temperature is OK now. " | ||
3098 | "temperature : %d Celsius\n", | ||
3099 | temp); | ||
3100 | } | ||
3101 | |||
3102 | /* Send temperature change event to applications */ | ||
3103 | shost = lpfc_shost_from_vport(phba->pport); | ||
3104 | fc_host_post_vendor_event(shost, fc_get_event_number(), | ||
3105 | sizeof(temp_event_data), (char *) &temp_event_data, | ||
3106 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | ||
3107 | |||
3108 | } | ||
3109 | |||
3110 | |||
2996 | int | 3111 | int |
2997 | lpfc_sli_setup(struct lpfc_hba *phba) | 3112 | lpfc_sli_setup(struct lpfc_hba *phba) |
2998 | { | 3113 | { |
@@ -3059,6 +3174,8 @@ lpfc_sli_setup(struct lpfc_hba *phba) | |||
3059 | pring->fast_iotag = 0; | 3174 | pring->fast_iotag = 0; |
3060 | pring->iotag_ctr = 0; | 3175 | pring->iotag_ctr = 0; |
3061 | pring->iotag_max = 4096; | 3176 | pring->iotag_max = 4096; |
3177 | pring->lpfc_sli_rcv_async_status = | ||
3178 | lpfc_sli_async_event_handler; | ||
3062 | pring->num_mask = 4; | 3179 | pring->num_mask = 4; |
3063 | pring->prt[0].profile = 0; /* Mask 0 */ | 3180 | pring->prt[0].profile = 0; /* Mask 0 */ |
3064 | pring->prt[0].rctl = FC_ELS_REQ; | 3181 | pring->prt[0].rctl = FC_ELS_REQ; |
@@ -3123,6 +3240,7 @@ lpfc_sli_queue_setup(struct lpfc_hba *phba) | |||
3123 | INIT_LIST_HEAD(&pring->txq); | 3240 | INIT_LIST_HEAD(&pring->txq); |
3124 | INIT_LIST_HEAD(&pring->txcmplq); | 3241 | INIT_LIST_HEAD(&pring->txcmplq); |
3125 | INIT_LIST_HEAD(&pring->iocb_continueq); | 3242 | INIT_LIST_HEAD(&pring->iocb_continueq); |
3243 | INIT_LIST_HEAD(&pring->iocb_continue_saveq); | ||
3126 | INIT_LIST_HEAD(&pring->postbufq); | 3244 | INIT_LIST_HEAD(&pring->postbufq); |
3127 | } | 3245 | } |
3128 | spin_unlock_irq(&phba->hbalock); | 3246 | spin_unlock_irq(&phba->hbalock); |
@@ -3193,6 +3311,7 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
3193 | LIST_HEAD(completions); | 3311 | LIST_HEAD(completions); |
3194 | struct lpfc_sli *psli = &phba->sli; | 3312 | struct lpfc_sli *psli = &phba->sli; |
3195 | struct lpfc_sli_ring *pring; | 3313 | struct lpfc_sli_ring *pring; |
3314 | struct lpfc_dmabuf *buf_ptr; | ||
3196 | LPFC_MBOXQ_t *pmb; | 3315 | LPFC_MBOXQ_t *pmb; |
3197 | struct lpfc_iocbq *iocb; | 3316 | struct lpfc_iocbq *iocb; |
3198 | IOCB_t *cmd = NULL; | 3317 | IOCB_t *cmd = NULL; |
@@ -3232,6 +3351,19 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
3232 | } | 3351 | } |
3233 | } | 3352 | } |
3234 | 3353 | ||
3354 | spin_lock_irqsave(&phba->hbalock, flags); | ||
3355 | list_splice_init(&phba->elsbuf, &completions); | ||
3356 | phba->elsbuf_cnt = 0; | ||
3357 | phba->elsbuf_prev_cnt = 0; | ||
3358 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
3359 | |||
3360 | while (!list_empty(&completions)) { | ||
3361 | list_remove_head(&completions, buf_ptr, | ||
3362 | struct lpfc_dmabuf, list); | ||
3363 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | ||
3364 | kfree(buf_ptr); | ||
3365 | } | ||
3366 | |||
3235 | /* Return any active mbox cmds */ | 3367 | /* Return any active mbox cmds */ |
3236 | del_timer_sync(&psli->mbox_tmo); | 3368 | del_timer_sync(&psli->mbox_tmo); |
3237 | spin_lock_irqsave(&phba->hbalock, flags); | 3369 | spin_lock_irqsave(&phba->hbalock, flags); |
@@ -3294,6 +3426,47 @@ lpfc_sli_ringpostbuf_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3294 | return 0; | 3426 | return 0; |
3295 | } | 3427 | } |
3296 | 3428 | ||
3429 | uint32_t | ||
3430 | lpfc_sli_get_buffer_tag(struct lpfc_hba *phba) | ||
3431 | { | ||
3432 | spin_lock_irq(&phba->hbalock); | ||
3433 | phba->buffer_tag_count++; | ||
3434 | /* | ||
3435 | * Always set the QUE_BUFTAG_BIT to distiguish between | ||
3436 | * a tag assigned by HBQ. | ||
3437 | */ | ||
3438 | phba->buffer_tag_count |= QUE_BUFTAG_BIT; | ||
3439 | spin_unlock_irq(&phba->hbalock); | ||
3440 | return phba->buffer_tag_count; | ||
3441 | } | ||
3442 | |||
3443 | struct lpfc_dmabuf * | ||
3444 | lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | ||
3445 | uint32_t tag) | ||
3446 | { | ||
3447 | struct lpfc_dmabuf *mp, *next_mp; | ||
3448 | struct list_head *slp = &pring->postbufq; | ||
3449 | |||
3450 | /* Search postbufq, from the begining, looking for a match on tag */ | ||
3451 | spin_lock_irq(&phba->hbalock); | ||
3452 | list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { | ||
3453 | if (mp->buffer_tag == tag) { | ||
3454 | list_del_init(&mp->list); | ||
3455 | pring->postbufq_cnt--; | ||
3456 | spin_unlock_irq(&phba->hbalock); | ||
3457 | return mp; | ||
3458 | } | ||
3459 | } | ||
3460 | |||
3461 | spin_unlock_irq(&phba->hbalock); | ||
3462 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
3463 | "0410 Cannot find virtual addr for buffer tag on " | ||
3464 | "ring %d Data x%lx x%p x%p x%x\n", | ||
3465 | pring->ringno, (unsigned long) tag, | ||
3466 | slp->next, slp->prev, pring->postbufq_cnt); | ||
3467 | |||
3468 | return NULL; | ||
3469 | } | ||
3297 | 3470 | ||
3298 | struct lpfc_dmabuf * | 3471 | struct lpfc_dmabuf * |
3299 | lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 3472 | lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
@@ -3361,6 +3534,12 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
3361 | pring->txcmplq_cnt--; | 3534 | pring->txcmplq_cnt--; |
3362 | spin_unlock_irq(&phba->hbalock); | 3535 | spin_unlock_irq(&phba->hbalock); |
3363 | 3536 | ||
3537 | /* Firmware could still be in progress of DMAing | ||
3538 | * payload, so don't free data buffer till after | ||
3539 | * a hbeat. | ||
3540 | */ | ||
3541 | abort_iocb->iocb_flag |= LPFC_DELAY_MEM_FREE; | ||
3542 | |||
3364 | abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED; | 3543 | abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED; |
3365 | abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; | 3544 | abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; |
3366 | abort_iocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED; | 3545 | abort_iocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED; |
@@ -3699,7 +3878,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, | |||
3699 | unsigned long flag; | 3878 | unsigned long flag; |
3700 | 3879 | ||
3701 | /* The caller must leave context1 empty. */ | 3880 | /* The caller must leave context1 empty. */ |
3702 | if (pmboxq->context1 != 0) | 3881 | if (pmboxq->context1) |
3703 | return MBX_NOT_FINISHED; | 3882 | return MBX_NOT_FINISHED; |
3704 | 3883 | ||
3705 | /* setup wake call as IOCB callback */ | 3884 | /* setup wake call as IOCB callback */ |
@@ -3771,7 +3950,6 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3771 | uint32_t ha_copy; | 3950 | uint32_t ha_copy; |
3772 | uint32_t work_ha_copy; | 3951 | uint32_t work_ha_copy; |
3773 | unsigned long status; | 3952 | unsigned long status; |
3774 | int i; | ||
3775 | uint32_t control; | 3953 | uint32_t control; |
3776 | 3954 | ||
3777 | MAILBOX_t *mbox, *pmbox; | 3955 | MAILBOX_t *mbox, *pmbox; |
@@ -3888,7 +4066,6 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3888 | } | 4066 | } |
3889 | 4067 | ||
3890 | if (work_ha_copy & HA_ERATT) { | 4068 | if (work_ha_copy & HA_ERATT) { |
3891 | phba->link_state = LPFC_HBA_ERROR; | ||
3892 | /* | 4069 | /* |
3893 | * There was a link/board error. Read the | 4070 | * There was a link/board error. Read the |
3894 | * status register to retrieve the error event | 4071 | * status register to retrieve the error event |
@@ -3920,7 +4097,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3920 | * Stray Mailbox Interrupt, mbxCommand <cmd> | 4097 | * Stray Mailbox Interrupt, mbxCommand <cmd> |
3921 | * mbxStatus <status> | 4098 | * mbxStatus <status> |
3922 | */ | 4099 | */ |
3923 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | | 4100 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | |
3924 | LOG_SLI, | 4101 | LOG_SLI, |
3925 | "(%d):0304 Stray Mailbox " | 4102 | "(%d):0304 Stray Mailbox " |
3926 | "Interrupt mbxCommand x%x " | 4103 | "Interrupt mbxCommand x%x " |
@@ -3928,51 +4105,60 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3928 | (vport ? vport->vpi : 0), | 4105 | (vport ? vport->vpi : 0), |
3929 | pmbox->mbxCommand, | 4106 | pmbox->mbxCommand, |
3930 | pmbox->mbxStatus); | 4107 | pmbox->mbxStatus); |
3931 | } | 4108 | /* clear mailbox attention bit */ |
3932 | phba->last_completion_time = jiffies; | 4109 | work_ha_copy &= ~HA_MBATT; |
3933 | del_timer_sync(&phba->sli.mbox_tmo); | 4110 | } else { |
3934 | 4111 | phba->last_completion_time = jiffies; | |
3935 | phba->sli.mbox_active = NULL; | 4112 | del_timer(&phba->sli.mbox_tmo); |
3936 | if (pmb->mbox_cmpl) { | ||
3937 | lpfc_sli_pcimem_bcopy(mbox, pmbox, | ||
3938 | MAILBOX_CMD_SIZE); | ||
3939 | } | ||
3940 | if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) { | ||
3941 | pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG; | ||
3942 | 4113 | ||
3943 | lpfc_debugfs_disc_trc(vport, | 4114 | phba->sli.mbox_active = NULL; |
3944 | LPFC_DISC_TRC_MBOX_VPORT, | 4115 | if (pmb->mbox_cmpl) { |
3945 | "MBOX dflt rpi: : status:x%x rpi:x%x", | 4116 | lpfc_sli_pcimem_bcopy(mbox, pmbox, |
3946 | (uint32_t)pmbox->mbxStatus, | 4117 | MAILBOX_CMD_SIZE); |
3947 | pmbox->un.varWords[0], 0); | 4118 | } |
3948 | 4119 | if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) { | |
3949 | if ( !pmbox->mbxStatus) { | 4120 | pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG; |
3950 | mp = (struct lpfc_dmabuf *) | 4121 | |
3951 | (pmb->context1); | 4122 | lpfc_debugfs_disc_trc(vport, |
3952 | ndlp = (struct lpfc_nodelist *) | 4123 | LPFC_DISC_TRC_MBOX_VPORT, |
3953 | pmb->context2; | 4124 | "MBOX dflt rpi: : " |
3954 | 4125 | "status:x%x rpi:x%x", | |
3955 | /* Reg_LOGIN of dflt RPI was successful. | 4126 | (uint32_t)pmbox->mbxStatus, |
3956 | * new lets get rid of the RPI using the | 4127 | pmbox->un.varWords[0], 0); |
3957 | * same mbox buffer. | 4128 | |
3958 | */ | 4129 | if (!pmbox->mbxStatus) { |
3959 | lpfc_unreg_login(phba, vport->vpi, | 4130 | mp = (struct lpfc_dmabuf *) |
3960 | pmbox->un.varWords[0], pmb); | 4131 | (pmb->context1); |
3961 | pmb->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | 4132 | ndlp = (struct lpfc_nodelist *) |
3962 | pmb->context1 = mp; | 4133 | pmb->context2; |
3963 | pmb->context2 = ndlp; | 4134 | |
3964 | pmb->vport = vport; | 4135 | /* Reg_LOGIN of dflt RPI was |
3965 | spin_lock(&phba->hbalock); | 4136 | * successful. new lets get |
3966 | phba->sli.sli_flag &= | 4137 | * rid of the RPI using the |
3967 | ~LPFC_SLI_MBOX_ACTIVE; | 4138 | * same mbox buffer. |
3968 | spin_unlock(&phba->hbalock); | 4139 | */ |
3969 | goto send_current_mbox; | 4140 | lpfc_unreg_login(phba, |
4141 | vport->vpi, | ||
4142 | pmbox->un.varWords[0], | ||
4143 | pmb); | ||
4144 | pmb->mbox_cmpl = | ||
4145 | lpfc_mbx_cmpl_dflt_rpi; | ||
4146 | pmb->context1 = mp; | ||
4147 | pmb->context2 = ndlp; | ||
4148 | pmb->vport = vport; | ||
4149 | spin_lock(&phba->hbalock); | ||
4150 | phba->sli.sli_flag &= | ||
4151 | ~LPFC_SLI_MBOX_ACTIVE; | ||
4152 | spin_unlock(&phba->hbalock); | ||
4153 | goto send_current_mbox; | ||
4154 | } | ||
3970 | } | 4155 | } |
4156 | spin_lock(&phba->pport->work_port_lock); | ||
4157 | phba->pport->work_port_events &= | ||
4158 | ~WORKER_MBOX_TMO; | ||
4159 | spin_unlock(&phba->pport->work_port_lock); | ||
4160 | lpfc_mbox_cmpl_put(phba, pmb); | ||
3971 | } | 4161 | } |
3972 | spin_lock(&phba->pport->work_port_lock); | ||
3973 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; | ||
3974 | spin_unlock(&phba->pport->work_port_lock); | ||
3975 | lpfc_mbox_cmpl_put(phba, pmb); | ||
3976 | } | 4162 | } |
3977 | if ((work_ha_copy & HA_MBATT) && | 4163 | if ((work_ha_copy & HA_MBATT) && |
3978 | (phba->sli.mbox_active == NULL)) { | 4164 | (phba->sli.mbox_active == NULL)) { |
@@ -3990,10 +4176,6 @@ send_current_mbox: | |||
3990 | lpfc_mbox_cmpl_put(phba, pmb); | 4176 | lpfc_mbox_cmpl_put(phba, pmb); |
3991 | goto send_next_mbox; | 4177 | goto send_next_mbox; |
3992 | } | 4178 | } |
3993 | } else { | ||
3994 | /* Turn on IOCB processing */ | ||
3995 | for (i = 0; i < phba->sli.num_rings; i++) | ||
3996 | lpfc_sli_turn_on_ring(phba, i); | ||
3997 | } | 4179 | } |
3998 | 4180 | ||
3999 | } | 4181 | } |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 51b2b6b949be..7249fd252cbb 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -33,6 +33,7 @@ typedef enum _lpfc_ctx_cmd { | |||
33 | struct lpfc_iocbq { | 33 | struct lpfc_iocbq { |
34 | /* lpfc_iocbqs are used in double linked lists */ | 34 | /* lpfc_iocbqs are used in double linked lists */ |
35 | struct list_head list; | 35 | struct list_head list; |
36 | struct list_head clist; | ||
36 | uint16_t iotag; /* pre-assigned IO tag */ | 37 | uint16_t iotag; /* pre-assigned IO tag */ |
37 | uint16_t rsvd1; | 38 | uint16_t rsvd1; |
38 | 39 | ||
@@ -44,6 +45,7 @@ struct lpfc_iocbq { | |||
44 | #define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */ | 45 | #define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */ |
45 | #define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */ | 46 | #define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */ |
46 | #define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */ | 47 | #define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */ |
48 | #define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */ | ||
47 | 49 | ||
48 | uint8_t abort_count; | 50 | uint8_t abort_count; |
49 | uint8_t rsvd2; | 51 | uint8_t rsvd2; |
@@ -92,8 +94,6 @@ typedef struct lpfcMboxq { | |||
92 | #define MBX_POLL 1 /* poll mailbox till command done, then | 94 | #define MBX_POLL 1 /* poll mailbox till command done, then |
93 | return */ | 95 | return */ |
94 | #define MBX_NOWAIT 2 /* issue command then return immediately */ | 96 | #define MBX_NOWAIT 2 /* issue command then return immediately */ |
95 | #define MBX_STOP_IOCB 4 /* Stop iocb processing till mbox cmds | ||
96 | complete */ | ||
97 | 97 | ||
98 | #define LPFC_MAX_RING_MASK 4 /* max num of rctl/type masks allowed per | 98 | #define LPFC_MAX_RING_MASK 4 /* max num of rctl/type masks allowed per |
99 | ring */ | 99 | ring */ |
@@ -129,9 +129,7 @@ struct lpfc_sli_ring { | |||
129 | uint16_t flag; /* ring flags */ | 129 | uint16_t flag; /* ring flags */ |
130 | #define LPFC_DEFERRED_RING_EVENT 0x001 /* Deferred processing a ring event */ | 130 | #define LPFC_DEFERRED_RING_EVENT 0x001 /* Deferred processing a ring event */ |
131 | #define LPFC_CALL_RING_AVAILABLE 0x002 /* indicates cmd was full */ | 131 | #define LPFC_CALL_RING_AVAILABLE 0x002 /* indicates cmd was full */ |
132 | #define LPFC_STOP_IOCB_MBX 0x010 /* Stop processing IOCB cmds mbox */ | ||
133 | #define LPFC_STOP_IOCB_EVENT 0x020 /* Stop processing IOCB cmds event */ | 132 | #define LPFC_STOP_IOCB_EVENT 0x020 /* Stop processing IOCB cmds event */ |
134 | #define LPFC_STOP_IOCB_MASK 0x030 /* Stop processing IOCB cmds mask */ | ||
135 | uint16_t abtsiotag; /* tracks next iotag to use for ABTS */ | 133 | uint16_t abtsiotag; /* tracks next iotag to use for ABTS */ |
136 | 134 | ||
137 | uint32_t local_getidx; /* last available cmd index (from cmdGetInx) */ | 135 | uint32_t local_getidx; /* last available cmd index (from cmdGetInx) */ |
@@ -163,9 +161,12 @@ struct lpfc_sli_ring { | |||
163 | struct list_head iocb_continueq; | 161 | struct list_head iocb_continueq; |
164 | uint16_t iocb_continueq_cnt; /* current length of queue */ | 162 | uint16_t iocb_continueq_cnt; /* current length of queue */ |
165 | uint16_t iocb_continueq_max; /* max length */ | 163 | uint16_t iocb_continueq_max; /* max length */ |
164 | struct list_head iocb_continue_saveq; | ||
166 | 165 | ||
167 | struct lpfc_sli_ring_mask prt[LPFC_MAX_RING_MASK]; | 166 | struct lpfc_sli_ring_mask prt[LPFC_MAX_RING_MASK]; |
168 | uint32_t num_mask; /* number of mask entries in prt array */ | 167 | uint32_t num_mask; /* number of mask entries in prt array */ |
168 | void (*lpfc_sli_rcv_async_status) (struct lpfc_hba *, | ||
169 | struct lpfc_sli_ring *, struct lpfc_iocbq *); | ||
169 | 170 | ||
170 | struct lpfc_sli_ring_stat stats; /* SLI statistical info */ | 171 | struct lpfc_sli_ring_stat stats; /* SLI statistical info */ |
171 | 172 | ||
@@ -199,9 +200,6 @@ struct lpfc_hbq_init { | |||
199 | uint32_t add_count; /* number to allocate when starved */ | 200 | uint32_t add_count; /* number to allocate when starved */ |
200 | } ; | 201 | } ; |
201 | 202 | ||
202 | #define LPFC_MAX_HBQ 16 | ||
203 | |||
204 | |||
205 | /* Structure used to hold SLI statistical counters and info */ | 203 | /* Structure used to hold SLI statistical counters and info */ |
206 | struct lpfc_sli_stat { | 204 | struct lpfc_sli_stat { |
207 | uint64_t mbox_stat_err; /* Mbox cmds completed status error */ | 205 | uint64_t mbox_stat_err; /* Mbox cmds completed status error */ |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 0081f49286bc..4b633d39a82a 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.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-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 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 | * * |
@@ -18,10 +18,10 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.2.2" | 21 | #define LPFC_DRIVER_VERSION "8.2.4" |
22 | 22 | ||
23 | #define LPFC_DRIVER_NAME "lpfc" | 23 | #define LPFC_DRIVER_NAME "lpfc" |
24 | 24 | ||
25 | #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ | 25 | #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ |
26 | LPFC_DRIVER_VERSION | 26 | LPFC_DRIVER_VERSION |
27 | #define LPFC_COPYRIGHT "Copyright(c) 2004-2007 Emulex. All rights reserved." | 27 | #define LPFC_COPYRIGHT "Copyright(c) 2004-2008 Emulex. All rights reserved." |
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index dcb415e717c3..9fad7663c117 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -125,15 +125,26 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
125 | pmb->vport = vport; | 125 | pmb->vport = vport; |
126 | rc = lpfc_sli_issue_mbox_wait(phba, pmb, phba->fc_ratov * 2); | 126 | rc = lpfc_sli_issue_mbox_wait(phba, pmb, phba->fc_ratov * 2); |
127 | if (rc != MBX_SUCCESS) { | 127 | if (rc != MBX_SUCCESS) { |
128 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT | LOG_VPORT, | 128 | if (signal_pending(current)) { |
129 | "1818 VPort failed init, mbxCmd x%x " | 129 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT | LOG_VPORT, |
130 | "READ_SPARM mbxStatus x%x, rc = x%x\n", | 130 | "1830 Signal aborted mbxCmd x%x\n", |
131 | mb->mbxCommand, mb->mbxStatus, rc); | 131 | mb->mbxCommand); |
132 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 132 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
133 | kfree(mp); | 133 | kfree(mp); |
134 | if (rc != MBX_TIMEOUT) | 134 | if (rc != MBX_TIMEOUT) |
135 | mempool_free(pmb, phba->mbox_mem_pool); | 135 | mempool_free(pmb, phba->mbox_mem_pool); |
136 | return -EIO; | 136 | return -EINTR; |
137 | } else { | ||
138 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT | LOG_VPORT, | ||
139 | "1818 VPort failed init, mbxCmd x%x " | ||
140 | "READ_SPARM mbxStatus x%x, rc = x%x\n", | ||
141 | mb->mbxCommand, mb->mbxStatus, rc); | ||
142 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
143 | kfree(mp); | ||
144 | if (rc != MBX_TIMEOUT) | ||
145 | mempool_free(pmb, phba->mbox_mem_pool); | ||
146 | return -EIO; | ||
147 | } | ||
137 | } | 148 | } |
138 | 149 | ||
139 | memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm)); | 150 | memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm)); |
@@ -204,6 +215,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) | |||
204 | int instance; | 215 | int instance; |
205 | int vpi; | 216 | int vpi; |
206 | int rc = VPORT_ERROR; | 217 | int rc = VPORT_ERROR; |
218 | int status; | ||
207 | 219 | ||
208 | if ((phba->sli_rev < 3) || | 220 | if ((phba->sli_rev < 3) || |
209 | !(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) { | 221 | !(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) { |
@@ -248,13 +260,19 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) | |||
248 | vport->vpi = vpi; | 260 | vport->vpi = vpi; |
249 | lpfc_debugfs_initialize(vport); | 261 | lpfc_debugfs_initialize(vport); |
250 | 262 | ||
251 | if (lpfc_vport_sparm(phba, vport)) { | 263 | if ((status = lpfc_vport_sparm(phba, vport))) { |
252 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, | 264 | if (status == -EINTR) { |
253 | "1813 Create VPORT failed. " | 265 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, |
254 | "Cannot get sparam\n"); | 266 | "1831 Create VPORT Interrupted.\n"); |
267 | rc = VPORT_ERROR; | ||
268 | } else { | ||
269 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, | ||
270 | "1813 Create VPORT failed. " | ||
271 | "Cannot get sparam\n"); | ||
272 | rc = VPORT_NORESOURCES; | ||
273 | } | ||
255 | lpfc_free_vpi(phba, vpi); | 274 | lpfc_free_vpi(phba, vpi); |
256 | destroy_port(vport); | 275 | destroy_port(vport); |
257 | rc = VPORT_NORESOURCES; | ||
258 | goto error_out; | 276 | goto error_out; |
259 | } | 277 | } |
260 | 278 | ||
@@ -427,7 +445,6 @@ int | |||
427 | lpfc_vport_delete(struct fc_vport *fc_vport) | 445 | lpfc_vport_delete(struct fc_vport *fc_vport) |
428 | { | 446 | { |
429 | struct lpfc_nodelist *ndlp = NULL; | 447 | struct lpfc_nodelist *ndlp = NULL; |
430 | struct lpfc_nodelist *next_ndlp; | ||
431 | struct Scsi_Host *shost = (struct Scsi_Host *) fc_vport->shost; | 448 | struct Scsi_Host *shost = (struct Scsi_Host *) fc_vport->shost; |
432 | struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; | 449 | struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; |
433 | struct lpfc_hba *phba = vport->phba; | 450 | struct lpfc_hba *phba = vport->phba; |
@@ -482,8 +499,18 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
482 | 499 | ||
483 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); | 500 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
484 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && | 501 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && |
485 | phba->link_state >= LPFC_LINK_UP) { | 502 | phba->link_state >= LPFC_LINK_UP) { |
486 | 503 | if (vport->cfg_enable_da_id) { | |
504 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); | ||
505 | if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0)) | ||
506 | while (vport->ct_flags && timeout) | ||
507 | timeout = schedule_timeout(timeout); | ||
508 | else | ||
509 | lpfc_printf_log(vport->phba, KERN_WARNING, | ||
510 | LOG_VPORT, | ||
511 | "1829 CT command failed to " | ||
512 | "delete objects on fabric. \n"); | ||
513 | } | ||
487 | /* First look for the Fabric ndlp */ | 514 | /* First look for the Fabric ndlp */ |
488 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | 515 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
489 | if (!ndlp) { | 516 | if (!ndlp) { |
@@ -503,23 +530,20 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
503 | } | 530 | } |
504 | 531 | ||
505 | skip_logo: | 532 | skip_logo: |
533 | lpfc_cleanup(vport); | ||
506 | lpfc_sli_host_down(vport); | 534 | lpfc_sli_host_down(vport); |
507 | 535 | ||
508 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { | ||
509 | lpfc_disc_state_machine(vport, ndlp, NULL, | ||
510 | NLP_EVT_DEVICE_RECOVERY); | ||
511 | lpfc_disc_state_machine(vport, ndlp, NULL, | ||
512 | NLP_EVT_DEVICE_RM); | ||
513 | } | ||
514 | |||
515 | lpfc_stop_vport_timers(vport); | 536 | lpfc_stop_vport_timers(vport); |
516 | lpfc_unreg_all_rpis(vport); | 537 | lpfc_unreg_all_rpis(vport); |
517 | lpfc_unreg_default_rpis(vport); | 538 | |
518 | /* | 539 | if (!(phba->pport->load_flag & FC_UNLOADING)) { |
519 | * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) does the | 540 | lpfc_unreg_default_rpis(vport); |
520 | * scsi_host_put() to release the vport. | 541 | /* |
521 | */ | 542 | * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) |
522 | lpfc_mbx_unreg_vpi(vport); | 543 | * does the scsi_host_put() to release the vport. |
544 | */ | ||
545 | lpfc_mbx_unreg_vpi(vport); | ||
546 | } | ||
523 | 547 | ||
524 | lpfc_free_vpi(phba, vport->vpi); | 548 | lpfc_free_vpi(phba, vport->vpi); |
525 | vport->work_port_events = 0; | 549 | vport->work_port_events = 0; |
@@ -532,16 +556,13 @@ skip_logo: | |||
532 | return VPORT_OK; | 556 | return VPORT_OK; |
533 | } | 557 | } |
534 | 558 | ||
535 | EXPORT_SYMBOL(lpfc_vport_create); | ||
536 | EXPORT_SYMBOL(lpfc_vport_delete); | ||
537 | |||
538 | struct lpfc_vport ** | 559 | struct lpfc_vport ** |
539 | lpfc_create_vport_work_array(struct lpfc_hba *phba) | 560 | lpfc_create_vport_work_array(struct lpfc_hba *phba) |
540 | { | 561 | { |
541 | struct lpfc_vport *port_iterator; | 562 | struct lpfc_vport *port_iterator; |
542 | struct lpfc_vport **vports; | 563 | struct lpfc_vport **vports; |
543 | int index = 0; | 564 | int index = 0; |
544 | vports = kzalloc(LPFC_MAX_VPORTS * sizeof(struct lpfc_vport *), | 565 | vports = kzalloc((phba->max_vpi + 1) * sizeof(struct lpfc_vport *), |
545 | GFP_KERNEL); | 566 | GFP_KERNEL); |
546 | if (vports == NULL) | 567 | if (vports == NULL) |
547 | return NULL; | 568 | return NULL; |
@@ -560,12 +581,12 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba) | |||
560 | } | 581 | } |
561 | 582 | ||
562 | void | 583 | void |
563 | lpfc_destroy_vport_work_array(struct lpfc_vport **vports) | 584 | lpfc_destroy_vport_work_array(struct lpfc_hba *phba, struct lpfc_vport **vports) |
564 | { | 585 | { |
565 | int i; | 586 | int i; |
566 | if (vports == NULL) | 587 | if (vports == NULL) |
567 | return; | 588 | return; |
568 | for (i=0; vports[i] != NULL && i < LPFC_MAX_VPORTS; i++) | 589 | for (i=0; vports[i] != NULL && i <= phba->max_vpi; i++) |
569 | scsi_host_put(lpfc_shost_from_vport(vports[i])); | 590 | scsi_host_put(lpfc_shost_from_vport(vports[i])); |
570 | kfree(vports); | 591 | kfree(vports); |
571 | } | 592 | } |
diff --git a/drivers/scsi/lpfc/lpfc_vport.h b/drivers/scsi/lpfc/lpfc_vport.h index 91da17751a37..96c445333b69 100644 --- a/drivers/scsi/lpfc/lpfc_vport.h +++ b/drivers/scsi/lpfc/lpfc_vport.h | |||
@@ -89,7 +89,7 @@ int lpfc_vport_delete(struct fc_vport *); | |||
89 | int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *); | 89 | int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *); |
90 | int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint); | 90 | int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint); |
91 | struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *); | 91 | struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *); |
92 | void lpfc_destroy_vport_work_array(struct lpfc_vport **); | 92 | void lpfc_destroy_vport_work_array(struct lpfc_hba *, struct lpfc_vport **); |
93 | 93 | ||
94 | /* | 94 | /* |
95 | * queuecommand VPORT-specific return codes. Specified in the host byte code. | 95 | * queuecommand VPORT-specific return codes. Specified in the host byte code. |