diff options
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 43 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 164 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 37 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 74 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_disc.h | 19 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 1012 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 575 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 65 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 265 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 33 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 391 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 25 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.h | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 470 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.h | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_version.h | 6 |
16 files changed, 2076 insertions, 1113 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 38ffa8d6e629..087c44539a16 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -121,7 +121,9 @@ struct lpfc_stats { | |||
121 | uint32_t elsRcvLOGO; | 121 | uint32_t elsRcvLOGO; |
122 | uint32_t elsRcvPRLO; | 122 | uint32_t elsRcvPRLO; |
123 | uint32_t elsRcvPRLI; | 123 | uint32_t elsRcvPRLI; |
124 | uint32_t elsRcvRRQ; | 124 | uint32_t elsRcvLIRR; |
125 | uint32_t elsRcvRPS; | ||
126 | uint32_t elsRcvRPL; | ||
125 | uint32_t elsXmitFLOGI; | 127 | uint32_t elsXmitFLOGI; |
126 | uint32_t elsXmitPLOGI; | 128 | uint32_t elsXmitPLOGI; |
127 | uint32_t elsXmitPRLI; | 129 | uint32_t elsXmitPRLI; |
@@ -167,33 +169,35 @@ struct lpfc_sysfs_mbox { | |||
167 | }; | 169 | }; |
168 | 170 | ||
169 | struct lpfc_hba { | 171 | struct lpfc_hba { |
170 | struct list_head hba_list; /* List of hbas/ports */ | ||
171 | struct lpfc_sli sli; | 172 | struct lpfc_sli sli; |
172 | struct lpfc_sli2_slim *slim2p; | 173 | struct lpfc_sli2_slim *slim2p; |
173 | dma_addr_t slim2p_mapping; | 174 | dma_addr_t slim2p_mapping; |
174 | uint16_t pci_cfg_value; | 175 | uint16_t pci_cfg_value; |
175 | 176 | ||
176 | struct semaphore hba_can_block; | 177 | struct semaphore hba_can_block; |
177 | uint32_t hba_state; | 178 | int32_t hba_state; |
178 | 179 | ||
179 | #define LPFC_INIT_START 1 /* Initial state after board reset */ | 180 | #define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */ |
180 | #define LPFC_INIT_MBX_CMDS 2 /* Initialize HBA with mbox commands */ | 181 | #define LPFC_WARM_START 1 /* HBA state after selective reset */ |
181 | #define LPFC_LINK_DOWN 3 /* HBA initialized, link is down */ | 182 | #define LPFC_INIT_START 2 /* Initial state after board reset */ |
182 | #define LPFC_LINK_UP 4 /* Link is up - issue READ_LA */ | 183 | #define LPFC_INIT_MBX_CMDS 3 /* Initialize HBA with mbox commands */ |
183 | #define LPFC_LOCAL_CFG_LINK 5 /* local NPORT Id configured */ | 184 | #define LPFC_LINK_DOWN 4 /* HBA initialized, link is down */ |
184 | #define LPFC_FLOGI 6 /* FLOGI sent to Fabric */ | 185 | #define LPFC_LINK_UP 5 /* Link is up - issue READ_LA */ |
185 | #define LPFC_FABRIC_CFG_LINK 7 /* Fabric assigned NPORT Id | 186 | #define LPFC_LOCAL_CFG_LINK 6 /* local NPORT Id configured */ |
187 | #define LPFC_FLOGI 7 /* FLOGI sent to Fabric */ | ||
188 | #define LPFC_FABRIC_CFG_LINK 8 /* Fabric assigned NPORT Id | ||
186 | configured */ | 189 | configured */ |
187 | #define LPFC_NS_REG 8 /* Register with NameServer */ | 190 | #define LPFC_NS_REG 9 /* Register with NameServer */ |
188 | #define LPFC_NS_QRY 9 /* Query NameServer for NPort ID list */ | 191 | #define LPFC_NS_QRY 10 /* Query NameServer for NPort ID list */ |
189 | #define LPFC_BUILD_DISC_LIST 10 /* Build ADISC and PLOGI lists for | 192 | #define LPFC_BUILD_DISC_LIST 11 /* Build ADISC and PLOGI lists for |
190 | * device authentication / discovery */ | 193 | * device authentication / discovery */ |
191 | #define LPFC_DISC_AUTH 11 /* Processing ADISC list */ | 194 | #define LPFC_DISC_AUTH 12 /* Processing ADISC list */ |
192 | #define LPFC_CLEAR_LA 12 /* authentication cmplt - issue | 195 | #define LPFC_CLEAR_LA 13 /* authentication cmplt - issue |
193 | CLEAR_LA */ | 196 | CLEAR_LA */ |
194 | #define LPFC_HBA_READY 32 | 197 | #define LPFC_HBA_READY 32 |
195 | #define LPFC_HBA_ERROR 0xff | 198 | #define LPFC_HBA_ERROR -1 |
196 | 199 | ||
200 | int32_t stopped; /* HBA has not been restarted since last ERATT */ | ||
197 | uint8_t fc_linkspeed; /* Link speed after last READ_LA */ | 201 | uint8_t fc_linkspeed; /* Link speed after last READ_LA */ |
198 | 202 | ||
199 | uint32_t fc_eventTag; /* event tag for link attention */ | 203 | uint32_t fc_eventTag; /* event tag for link attention */ |
@@ -245,6 +249,7 @@ struct lpfc_hba { | |||
245 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ | 249 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ |
246 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ | 250 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ |
247 | #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ | 251 | #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ |
252 | #define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ | ||
248 | 253 | ||
249 | uint32_t fc_topology; /* link topology, from LINK INIT */ | 254 | uint32_t fc_topology; /* link topology, from LINK INIT */ |
250 | 255 | ||
@@ -289,8 +294,8 @@ struct lpfc_hba { | |||
289 | uint32_t cfg_link_speed; | 294 | uint32_t cfg_link_speed; |
290 | uint32_t cfg_cr_delay; | 295 | uint32_t cfg_cr_delay; |
291 | uint32_t cfg_cr_count; | 296 | uint32_t cfg_cr_count; |
297 | uint32_t cfg_multi_ring_support; | ||
292 | uint32_t cfg_fdmi_on; | 298 | uint32_t cfg_fdmi_on; |
293 | uint32_t cfg_fcp_bind_method; | ||
294 | uint32_t cfg_discovery_threads; | 299 | uint32_t cfg_discovery_threads; |
295 | uint32_t cfg_max_luns; | 300 | uint32_t cfg_max_luns; |
296 | uint32_t cfg_poll; | 301 | uint32_t cfg_poll; |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 5625a8c2a8fd..b62a72dfab29 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-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -79,7 +79,7 @@ static ssize_t | |||
79 | lpfc_serialnum_show(struct class_device *cdev, char *buf) | 79 | lpfc_serialnum_show(struct class_device *cdev, char *buf) |
80 | { | 80 | { |
81 | struct Scsi_Host *host = class_to_shost(cdev); | 81 | struct Scsi_Host *host = class_to_shost(cdev); |
82 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 82 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
83 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber); | 83 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber); |
84 | } | 84 | } |
85 | 85 | ||
@@ -87,7 +87,7 @@ static ssize_t | |||
87 | lpfc_modeldesc_show(struct class_device *cdev, char *buf) | 87 | lpfc_modeldesc_show(struct class_device *cdev, char *buf) |
88 | { | 88 | { |
89 | struct Scsi_Host *host = class_to_shost(cdev); | 89 | struct Scsi_Host *host = class_to_shost(cdev); |
90 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 90 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
91 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc); | 91 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc); |
92 | } | 92 | } |
93 | 93 | ||
@@ -95,7 +95,7 @@ static ssize_t | |||
95 | lpfc_modelname_show(struct class_device *cdev, char *buf) | 95 | lpfc_modelname_show(struct class_device *cdev, char *buf) |
96 | { | 96 | { |
97 | struct Scsi_Host *host = class_to_shost(cdev); | 97 | struct Scsi_Host *host = class_to_shost(cdev); |
98 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 98 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
99 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName); | 99 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName); |
100 | } | 100 | } |
101 | 101 | ||
@@ -103,7 +103,7 @@ static ssize_t | |||
103 | lpfc_programtype_show(struct class_device *cdev, char *buf) | 103 | lpfc_programtype_show(struct class_device *cdev, char *buf) |
104 | { | 104 | { |
105 | struct Scsi_Host *host = class_to_shost(cdev); | 105 | struct Scsi_Host *host = class_to_shost(cdev); |
106 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 106 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
107 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType); | 107 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType); |
108 | } | 108 | } |
109 | 109 | ||
@@ -111,7 +111,7 @@ static ssize_t | |||
111 | lpfc_portnum_show(struct class_device *cdev, char *buf) | 111 | lpfc_portnum_show(struct class_device *cdev, char *buf) |
112 | { | 112 | { |
113 | struct Scsi_Host *host = class_to_shost(cdev); | 113 | struct Scsi_Host *host = class_to_shost(cdev); |
114 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 114 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
115 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port); | 115 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port); |
116 | } | 116 | } |
117 | 117 | ||
@@ -119,7 +119,7 @@ static ssize_t | |||
119 | lpfc_fwrev_show(struct class_device *cdev, char *buf) | 119 | lpfc_fwrev_show(struct class_device *cdev, char *buf) |
120 | { | 120 | { |
121 | struct Scsi_Host *host = class_to_shost(cdev); | 121 | struct Scsi_Host *host = class_to_shost(cdev); |
122 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 122 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
123 | char fwrev[32]; | 123 | char fwrev[32]; |
124 | lpfc_decode_firmware_rev(phba, fwrev, 1); | 124 | lpfc_decode_firmware_rev(phba, fwrev, 1); |
125 | return snprintf(buf, PAGE_SIZE, "%s\n",fwrev); | 125 | return snprintf(buf, PAGE_SIZE, "%s\n",fwrev); |
@@ -130,7 +130,7 @@ lpfc_hdw_show(struct class_device *cdev, char *buf) | |||
130 | { | 130 | { |
131 | char hdw[9]; | 131 | char hdw[9]; |
132 | struct Scsi_Host *host = class_to_shost(cdev); | 132 | struct Scsi_Host *host = class_to_shost(cdev); |
133 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 133 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
134 | lpfc_vpd_t *vp = &phba->vpd; | 134 | lpfc_vpd_t *vp = &phba->vpd; |
135 | lpfc_jedec_to_ascii(vp->rev.biuRev, hdw); | 135 | lpfc_jedec_to_ascii(vp->rev.biuRev, hdw); |
136 | return snprintf(buf, PAGE_SIZE, "%s\n", hdw); | 136 | return snprintf(buf, PAGE_SIZE, "%s\n", hdw); |
@@ -139,16 +139,18 @@ static ssize_t | |||
139 | lpfc_option_rom_version_show(struct class_device *cdev, char *buf) | 139 | lpfc_option_rom_version_show(struct class_device *cdev, char *buf) |
140 | { | 140 | { |
141 | struct Scsi_Host *host = class_to_shost(cdev); | 141 | struct Scsi_Host *host = class_to_shost(cdev); |
142 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 142 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
143 | return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion); | 143 | return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion); |
144 | } | 144 | } |
145 | static ssize_t | 145 | static ssize_t |
146 | lpfc_state_show(struct class_device *cdev, char *buf) | 146 | lpfc_state_show(struct class_device *cdev, char *buf) |
147 | { | 147 | { |
148 | struct Scsi_Host *host = class_to_shost(cdev); | 148 | struct Scsi_Host *host = class_to_shost(cdev); |
149 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 149 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
150 | int len = 0; | 150 | int len = 0; |
151 | switch (phba->hba_state) { | 151 | switch (phba->hba_state) { |
152 | case LPFC_STATE_UNKNOWN: | ||
153 | case LPFC_WARM_START: | ||
152 | case LPFC_INIT_START: | 154 | case LPFC_INIT_START: |
153 | case LPFC_INIT_MBX_CMDS: | 155 | case LPFC_INIT_MBX_CMDS: |
154 | case LPFC_LINK_DOWN: | 156 | case LPFC_LINK_DOWN: |
@@ -194,7 +196,7 @@ static ssize_t | |||
194 | lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) | 196 | lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) |
195 | { | 197 | { |
196 | struct Scsi_Host *host = class_to_shost(cdev); | 198 | struct Scsi_Host *host = class_to_shost(cdev); |
197 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 199 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
198 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt + | 200 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt + |
199 | phba->fc_unmap_cnt); | 201 | phba->fc_unmap_cnt); |
200 | } | 202 | } |
@@ -203,7 +205,7 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) | |||
203 | static int | 205 | static int |
204 | lpfc_issue_lip(struct Scsi_Host *host) | 206 | lpfc_issue_lip(struct Scsi_Host *host) |
205 | { | 207 | { |
206 | struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0]; | 208 | struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata; |
207 | LPFC_MBOXQ_t *pmboxq; | 209 | LPFC_MBOXQ_t *pmboxq; |
208 | int mbxstatus = MBXERR_ERROR; | 210 | int mbxstatus = MBXERR_ERROR; |
209 | 211 | ||
@@ -235,7 +237,7 @@ static ssize_t | |||
235 | lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) | 237 | lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) |
236 | { | 238 | { |
237 | struct Scsi_Host *host = class_to_shost(cdev); | 239 | struct Scsi_Host *host = class_to_shost(cdev); |
238 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 240 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
239 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); | 241 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); |
240 | } | 242 | } |
241 | 243 | ||
@@ -243,7 +245,7 @@ static ssize_t | |||
243 | lpfc_board_online_show(struct class_device *cdev, char *buf) | 245 | lpfc_board_online_show(struct class_device *cdev, char *buf) |
244 | { | 246 | { |
245 | struct Scsi_Host *host = class_to_shost(cdev); | 247 | struct Scsi_Host *host = class_to_shost(cdev); |
246 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 248 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
247 | 249 | ||
248 | if (phba->fc_flag & FC_OFFLINE_MODE) | 250 | if (phba->fc_flag & FC_OFFLINE_MODE) |
249 | return snprintf(buf, PAGE_SIZE, "0\n"); | 251 | return snprintf(buf, PAGE_SIZE, "0\n"); |
@@ -256,7 +258,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf, | |||
256 | size_t count) | 258 | size_t count) |
257 | { | 259 | { |
258 | struct Scsi_Host *host = class_to_shost(cdev); | 260 | struct Scsi_Host *host = class_to_shost(cdev); |
259 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 261 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
260 | struct completion online_compl; | 262 | struct completion online_compl; |
261 | int val=0, status=0; | 263 | int val=0, status=0; |
262 | 264 | ||
@@ -279,10 +281,62 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf, | |||
279 | } | 281 | } |
280 | 282 | ||
281 | static ssize_t | 283 | static ssize_t |
284 | lpfc_board_mode_show(struct class_device *cdev, char *buf) | ||
285 | { | ||
286 | struct Scsi_Host *host = class_to_shost(cdev); | ||
287 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | ||
288 | char * state; | ||
289 | |||
290 | if (phba->hba_state == LPFC_HBA_ERROR) | ||
291 | state = "error"; | ||
292 | else if (phba->hba_state == LPFC_WARM_START) | ||
293 | state = "warm start"; | ||
294 | else if (phba->hba_state == LPFC_INIT_START) | ||
295 | state = "offline"; | ||
296 | else | ||
297 | state = "online"; | ||
298 | |||
299 | return snprintf(buf, PAGE_SIZE, "%s\n", state); | ||
300 | } | ||
301 | |||
302 | static ssize_t | ||
303 | lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) | ||
304 | { | ||
305 | struct Scsi_Host *host = class_to_shost(cdev); | ||
306 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | ||
307 | struct completion online_compl; | ||
308 | int status=0; | ||
309 | |||
310 | init_completion(&online_compl); | ||
311 | |||
312 | if(strncmp(buf, "online", sizeof("online") - 1) == 0) | ||
313 | lpfc_workq_post_event(phba, &status, &online_compl, | ||
314 | LPFC_EVT_ONLINE); | ||
315 | else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) | ||
316 | lpfc_workq_post_event(phba, &status, &online_compl, | ||
317 | LPFC_EVT_OFFLINE); | ||
318 | else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0) | ||
319 | lpfc_workq_post_event(phba, &status, &online_compl, | ||
320 | LPFC_EVT_WARM_START); | ||
321 | else if (strncmp(buf, "error", sizeof("error") - 1) == 0) | ||
322 | lpfc_workq_post_event(phba, &status, &online_compl, | ||
323 | LPFC_EVT_KILL); | ||
324 | else | ||
325 | return -EINVAL; | ||
326 | |||
327 | wait_for_completion(&online_compl); | ||
328 | |||
329 | if (!status) | ||
330 | return strlen(buf); | ||
331 | else | ||
332 | return -EIO; | ||
333 | } | ||
334 | |||
335 | static ssize_t | ||
282 | lpfc_poll_show(struct class_device *cdev, char *buf) | 336 | lpfc_poll_show(struct class_device *cdev, char *buf) |
283 | { | 337 | { |
284 | struct Scsi_Host *host = class_to_shost(cdev); | 338 | struct Scsi_Host *host = class_to_shost(cdev); |
285 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 339 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
286 | 340 | ||
287 | return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll); | 341 | return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll); |
288 | } | 342 | } |
@@ -292,7 +346,7 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, | |||
292 | size_t count) | 346 | size_t count) |
293 | { | 347 | { |
294 | struct Scsi_Host *host = class_to_shost(cdev); | 348 | struct Scsi_Host *host = class_to_shost(cdev); |
295 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 349 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
296 | uint32_t creg_val; | 350 | uint32_t creg_val; |
297 | uint32_t old_val; | 351 | uint32_t old_val; |
298 | int val=0; | 352 | int val=0; |
@@ -349,7 +403,7 @@ static ssize_t \ | |||
349 | lpfc_##attr##_show(struct class_device *cdev, char *buf) \ | 403 | lpfc_##attr##_show(struct class_device *cdev, char *buf) \ |
350 | { \ | 404 | { \ |
351 | struct Scsi_Host *host = class_to_shost(cdev);\ | 405 | struct Scsi_Host *host = class_to_shost(cdev);\ |
352 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ | 406 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ |
353 | int val = 0;\ | 407 | int val = 0;\ |
354 | val = phba->cfg_##attr;\ | 408 | val = phba->cfg_##attr;\ |
355 | return snprintf(buf, PAGE_SIZE, "%d\n",\ | 409 | return snprintf(buf, PAGE_SIZE, "%d\n",\ |
@@ -361,7 +415,7 @@ static ssize_t \ | |||
361 | lpfc_##attr##_show(struct class_device *cdev, char *buf) \ | 415 | lpfc_##attr##_show(struct class_device *cdev, char *buf) \ |
362 | { \ | 416 | { \ |
363 | struct Scsi_Host *host = class_to_shost(cdev);\ | 417 | struct Scsi_Host *host = class_to_shost(cdev);\ |
364 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ | 418 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ |
365 | int val = 0;\ | 419 | int val = 0;\ |
366 | val = phba->cfg_##attr;\ | 420 | val = phba->cfg_##attr;\ |
367 | return snprintf(buf, PAGE_SIZE, "%#x\n",\ | 421 | return snprintf(buf, PAGE_SIZE, "%#x\n",\ |
@@ -404,7 +458,7 @@ static ssize_t \ | |||
404 | lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ | 458 | lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ |
405 | { \ | 459 | { \ |
406 | struct Scsi_Host *host = class_to_shost(cdev);\ | 460 | struct Scsi_Host *host = class_to_shost(cdev);\ |
407 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ | 461 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ |
408 | int val=0;\ | 462 | int val=0;\ |
409 | if (!isdigit(buf[0]))\ | 463 | if (!isdigit(buf[0]))\ |
410 | return -EINVAL;\ | 464 | return -EINVAL;\ |
@@ -480,6 +534,8 @@ static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, | |||
480 | NULL); | 534 | NULL); |
481 | static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, | 535 | static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, |
482 | lpfc_board_online_show, lpfc_board_online_store); | 536 | lpfc_board_online_show, lpfc_board_online_store); |
537 | static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, | ||
538 | lpfc_board_mode_show, lpfc_board_mode_store); | ||
483 | 539 | ||
484 | static int lpfc_poll = 0; | 540 | static int lpfc_poll = 0; |
485 | module_param(lpfc_poll, int, 0); | 541 | module_param(lpfc_poll, int, 0); |
@@ -520,6 +576,16 @@ LPFC_ATTR_R(lun_queue_depth, 30, 1, 128, | |||
520 | "Max number of FCP commands we can queue to a specific LUN"); | 576 | "Max number of FCP commands we can queue to a specific LUN"); |
521 | 577 | ||
522 | /* | 578 | /* |
579 | # hba_queue_depth: This parameter is used to limit the number of outstanding | ||
580 | # commands per lpfc HBA. Value range is [32,8192]. If this parameter | ||
581 | # value is greater than the maximum number of exchanges supported by the HBA, | ||
582 | # then maximum number of exchanges supported by the HBA is used to determine | ||
583 | # the hba_queue_depth. | ||
584 | */ | ||
585 | LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192, | ||
586 | "Max number of FCP commands we can queue to a lpfc HBA"); | ||
587 | |||
588 | /* | ||
523 | # Some disk devices have a "select ID" or "select Target" capability. | 589 | # Some disk devices have a "select ID" or "select Target" capability. |
524 | # From a protocol standpoint "select ID" usually means select the | 590 | # From a protocol standpoint "select ID" usually means select the |
525 | # Fibre channel "ALPA". In the FC-AL Profile there is an "informative | 591 | # Fibre channel "ALPA". In the FC-AL Profile there is an "informative |
@@ -550,6 +616,7 @@ LPFC_ATTR_RW(nodev_tmo, 30, 0, 255, | |||
550 | /* | 616 | /* |
551 | # lpfc_topology: link topology for init link | 617 | # lpfc_topology: link topology for init link |
552 | # 0x0 = attempt loop mode then point-to-point | 618 | # 0x0 = attempt loop mode then point-to-point |
619 | # 0x01 = internal loopback mode | ||
553 | # 0x02 = attempt point-to-point mode only | 620 | # 0x02 = attempt point-to-point mode only |
554 | # 0x04 = attempt loop mode only | 621 | # 0x04 = attempt loop mode only |
555 | # 0x06 = attempt point-to-point mode then loop | 622 | # 0x06 = attempt point-to-point mode then loop |
@@ -557,7 +624,7 @@ LPFC_ATTR_RW(nodev_tmo, 30, 0, 255, | |||
557 | # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6]. | 624 | # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6]. |
558 | # Default value is 0. | 625 | # Default value is 0. |
559 | */ | 626 | */ |
560 | LPFC_ATTR_R(topology, 0, 0, 6, "Select Fibre Channel topology"); | 627 | LPFC_ATTR_RW(topology, 0, 0, 6, "Select Fibre Channel topology"); |
561 | 628 | ||
562 | /* | 629 | /* |
563 | # lpfc_link_speed: Link speed selection for initializing the Fibre Channel | 630 | # lpfc_link_speed: Link speed selection for initializing the Fibre Channel |
@@ -597,13 +664,21 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support"); | |||
597 | # is 0. Default value of cr_count is 1. The cr_count feature is disabled if | 664 | # is 0. Default value of cr_count is 1. The cr_count feature is disabled if |
598 | # cr_delay is set to 0. | 665 | # cr_delay is set to 0. |
599 | */ | 666 | */ |
600 | LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an" | 667 | LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an " |
601 | "interrupt response is generated"); | 668 | "interrupt response is generated"); |
602 | 669 | ||
603 | LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an" | 670 | LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an " |
604 | "interrupt response is generated"); | 671 | "interrupt response is generated"); |
605 | 672 | ||
606 | /* | 673 | /* |
674 | # lpfc_multi_ring_support: Determines how many rings to spread available | ||
675 | # cmd/rsp IOCB entries across. | ||
676 | # Value range is [1,2]. Default value is 1. | ||
677 | */ | ||
678 | LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary " | ||
679 | "SLI rings to spread IOCB entries across"); | ||
680 | |||
681 | /* | ||
607 | # lpfc_fdmi_on: controls FDMI support. | 682 | # lpfc_fdmi_on: controls FDMI support. |
608 | # 0 = no FDMI support | 683 | # 0 = no FDMI support |
609 | # 1 = support FDMI without attribute of hostname | 684 | # 1 = support FDMI without attribute of hostname |
@@ -616,7 +691,7 @@ LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support"); | |||
616 | # Specifies the maximum number of ELS cmds we can have outstanding (for | 691 | # Specifies the maximum number of ELS cmds we can have outstanding (for |
617 | # discovery). Value range is [1,64]. Default value = 32. | 692 | # discovery). Value range is [1,64]. Default value = 32. |
618 | */ | 693 | */ |
619 | LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands" | 694 | LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands " |
620 | "during discovery"); | 695 | "during discovery"); |
621 | 696 | ||
622 | /* | 697 | /* |
@@ -649,6 +724,7 @@ struct class_device_attribute *lpfc_host_attrs[] = { | |||
649 | &class_device_attr_lpfc_drvr_version, | 724 | &class_device_attr_lpfc_drvr_version, |
650 | &class_device_attr_lpfc_log_verbose, | 725 | &class_device_attr_lpfc_log_verbose, |
651 | &class_device_attr_lpfc_lun_queue_depth, | 726 | &class_device_attr_lpfc_lun_queue_depth, |
727 | &class_device_attr_lpfc_hba_queue_depth, | ||
652 | &class_device_attr_lpfc_nodev_tmo, | 728 | &class_device_attr_lpfc_nodev_tmo, |
653 | &class_device_attr_lpfc_fcp_class, | 729 | &class_device_attr_lpfc_fcp_class, |
654 | &class_device_attr_lpfc_use_adisc, | 730 | &class_device_attr_lpfc_use_adisc, |
@@ -658,11 +734,13 @@ struct class_device_attribute *lpfc_host_attrs[] = { | |||
658 | &class_device_attr_lpfc_link_speed, | 734 | &class_device_attr_lpfc_link_speed, |
659 | &class_device_attr_lpfc_cr_delay, | 735 | &class_device_attr_lpfc_cr_delay, |
660 | &class_device_attr_lpfc_cr_count, | 736 | &class_device_attr_lpfc_cr_count, |
737 | &class_device_attr_lpfc_multi_ring_support, | ||
661 | &class_device_attr_lpfc_fdmi_on, | 738 | &class_device_attr_lpfc_fdmi_on, |
662 | &class_device_attr_lpfc_max_luns, | 739 | &class_device_attr_lpfc_max_luns, |
663 | &class_device_attr_nport_evt_cnt, | 740 | &class_device_attr_nport_evt_cnt, |
664 | &class_device_attr_management_version, | 741 | &class_device_attr_management_version, |
665 | &class_device_attr_board_online, | 742 | &class_device_attr_board_online, |
743 | &class_device_attr_board_mode, | ||
666 | &class_device_attr_lpfc_poll, | 744 | &class_device_attr_lpfc_poll, |
667 | &class_device_attr_lpfc_poll_tmo, | 745 | &class_device_attr_lpfc_poll_tmo, |
668 | NULL, | 746 | NULL, |
@@ -674,7 +752,7 @@ sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
674 | size_t buf_off; | 752 | size_t buf_off; |
675 | struct Scsi_Host *host = class_to_shost(container_of(kobj, | 753 | struct Scsi_Host *host = class_to_shost(container_of(kobj, |
676 | struct class_device, kobj)); | 754 | struct class_device, kobj)); |
677 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 755 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
678 | 756 | ||
679 | if ((off + count) > FF_REG_AREA_SIZE) | 757 | if ((off + count) > FF_REG_AREA_SIZE) |
680 | return -ERANGE; | 758 | return -ERANGE; |
@@ -707,7 +785,7 @@ sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
707 | uint32_t * tmp_ptr; | 785 | uint32_t * tmp_ptr; |
708 | struct Scsi_Host *host = class_to_shost(container_of(kobj, | 786 | struct Scsi_Host *host = class_to_shost(container_of(kobj, |
709 | struct class_device, kobj)); | 787 | struct class_device, kobj)); |
710 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 788 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
711 | 789 | ||
712 | if (off > FF_REG_AREA_SIZE) | 790 | if (off > FF_REG_AREA_SIZE) |
713 | return -ERANGE; | 791 | return -ERANGE; |
@@ -762,7 +840,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
762 | { | 840 | { |
763 | struct Scsi_Host * host = | 841 | struct Scsi_Host * host = |
764 | class_to_shost(container_of(kobj, struct class_device, kobj)); | 842 | class_to_shost(container_of(kobj, struct class_device, kobj)); |
765 | struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata[0]; | 843 | struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata; |
766 | struct lpfcMboxq * mbox = NULL; | 844 | struct lpfcMboxq * mbox = NULL; |
767 | 845 | ||
768 | if ((count + off) > MAILBOX_CMD_SIZE) | 846 | if ((count + off) > MAILBOX_CMD_SIZE) |
@@ -778,7 +856,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
778 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 856 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
779 | if (!mbox) | 857 | if (!mbox) |
780 | return -ENOMEM; | 858 | return -ENOMEM; |
781 | 859 | memset(mbox, 0, sizeof (LPFC_MBOXQ_t)); | |
782 | } | 860 | } |
783 | 861 | ||
784 | spin_lock_irq(host->host_lock); | 862 | spin_lock_irq(host->host_lock); |
@@ -815,7 +893,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
815 | struct Scsi_Host *host = | 893 | struct Scsi_Host *host = |
816 | class_to_shost(container_of(kobj, struct class_device, | 894 | class_to_shost(container_of(kobj, struct class_device, |
817 | kobj)); | 895 | kobj)); |
818 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; | 896 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
819 | int rc; | 897 | int rc; |
820 | 898 | ||
821 | if (off > sizeof(MAILBOX_t)) | 899 | if (off > sizeof(MAILBOX_t)) |
@@ -872,8 +950,11 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
872 | case MBX_DUMP_MEMORY: | 950 | case MBX_DUMP_MEMORY: |
873 | case MBX_DOWN_LOAD: | 951 | case MBX_DOWN_LOAD: |
874 | case MBX_UPDATE_CFG: | 952 | case MBX_UPDATE_CFG: |
953 | case MBX_KILL_BOARD: | ||
875 | case MBX_LOAD_AREA: | 954 | case MBX_LOAD_AREA: |
876 | case MBX_LOAD_EXP_ROM: | 955 | case MBX_LOAD_EXP_ROM: |
956 | case MBX_BEACON: | ||
957 | case MBX_DEL_LD_ENTRY: | ||
877 | break; | 958 | break; |
878 | case MBX_READ_SPARM64: | 959 | case MBX_READ_SPARM64: |
879 | case MBX_READ_LA: | 960 | case MBX_READ_LA: |
@@ -990,7 +1071,7 @@ lpfc_free_sysfs_attr(struct lpfc_hba *phba) | |||
990 | static void | 1071 | static void |
991 | lpfc_get_host_port_id(struct Scsi_Host *shost) | 1072 | lpfc_get_host_port_id(struct Scsi_Host *shost) |
992 | { | 1073 | { |
993 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; | 1074 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; |
994 | /* note: fc_myDID already in cpu endianness */ | 1075 | /* note: fc_myDID already in cpu endianness */ |
995 | fc_host_port_id(shost) = phba->fc_myDID; | 1076 | fc_host_port_id(shost) = phba->fc_myDID; |
996 | } | 1077 | } |
@@ -998,7 +1079,7 @@ lpfc_get_host_port_id(struct Scsi_Host *shost) | |||
998 | static void | 1079 | static void |
999 | lpfc_get_host_port_type(struct Scsi_Host *shost) | 1080 | lpfc_get_host_port_type(struct Scsi_Host *shost) |
1000 | { | 1081 | { |
1001 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; | 1082 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; |
1002 | 1083 | ||
1003 | spin_lock_irq(shost->host_lock); | 1084 | spin_lock_irq(shost->host_lock); |
1004 | 1085 | ||
@@ -1023,7 +1104,7 @@ lpfc_get_host_port_type(struct Scsi_Host *shost) | |||
1023 | static void | 1104 | static void |
1024 | lpfc_get_host_port_state(struct Scsi_Host *shost) | 1105 | lpfc_get_host_port_state(struct Scsi_Host *shost) |
1025 | { | 1106 | { |
1026 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; | 1107 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; |
1027 | 1108 | ||
1028 | spin_lock_irq(shost->host_lock); | 1109 | spin_lock_irq(shost->host_lock); |
1029 | 1110 | ||
@@ -1031,6 +1112,8 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) | |||
1031 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; | 1112 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; |
1032 | else { | 1113 | else { |
1033 | switch (phba->hba_state) { | 1114 | switch (phba->hba_state) { |
1115 | case LPFC_STATE_UNKNOWN: | ||
1116 | case LPFC_WARM_START: | ||
1034 | case LPFC_INIT_START: | 1117 | case LPFC_INIT_START: |
1035 | case LPFC_INIT_MBX_CMDS: | 1118 | case LPFC_INIT_MBX_CMDS: |
1036 | case LPFC_LINK_DOWN: | 1119 | case LPFC_LINK_DOWN: |
@@ -1064,7 +1147,7 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) | |||
1064 | static void | 1147 | static void |
1065 | lpfc_get_host_speed(struct Scsi_Host *shost) | 1148 | lpfc_get_host_speed(struct Scsi_Host *shost) |
1066 | { | 1149 | { |
1067 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; | 1150 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; |
1068 | 1151 | ||
1069 | spin_lock_irq(shost->host_lock); | 1152 | spin_lock_irq(shost->host_lock); |
1070 | 1153 | ||
@@ -1091,7 +1174,7 @@ lpfc_get_host_speed(struct Scsi_Host *shost) | |||
1091 | static void | 1174 | static void |
1092 | lpfc_get_host_fabric_name (struct Scsi_Host *shost) | 1175 | lpfc_get_host_fabric_name (struct Scsi_Host *shost) |
1093 | { | 1176 | { |
1094 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0]; | 1177 | struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; |
1095 | u64 node_name; | 1178 | u64 node_name; |
1096 | 1179 | ||
1097 | spin_lock_irq(shost->host_lock); | 1180 | spin_lock_irq(shost->host_lock); |
@@ -1113,7 +1196,7 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost) | |||
1113 | static struct fc_host_statistics * | 1196 | static struct fc_host_statistics * |
1114 | lpfc_get_stats(struct Scsi_Host *shost) | 1197 | lpfc_get_stats(struct Scsi_Host *shost) |
1115 | { | 1198 | { |
1116 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; | 1199 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; |
1117 | struct lpfc_sli *psli = &phba->sli; | 1200 | struct lpfc_sli *psli = &phba->sli; |
1118 | struct fc_host_statistics *hs = &phba->link_stats; | 1201 | struct fc_host_statistics *hs = &phba->link_stats; |
1119 | LPFC_MBOXQ_t *pmboxq; | 1202 | LPFC_MBOXQ_t *pmboxq; |
@@ -1203,7 +1286,7 @@ static void | |||
1203 | lpfc_get_starget_port_id(struct scsi_target *starget) | 1286 | lpfc_get_starget_port_id(struct scsi_target *starget) |
1204 | { | 1287 | { |
1205 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 1288 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
1206 | struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; | 1289 | struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; |
1207 | uint32_t did = -1; | 1290 | uint32_t did = -1; |
1208 | struct lpfc_nodelist *ndlp = NULL; | 1291 | struct lpfc_nodelist *ndlp = NULL; |
1209 | 1292 | ||
@@ -1224,7 +1307,7 @@ static void | |||
1224 | lpfc_get_starget_node_name(struct scsi_target *starget) | 1307 | lpfc_get_starget_node_name(struct scsi_target *starget) |
1225 | { | 1308 | { |
1226 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 1309 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
1227 | struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; | 1310 | struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; |
1228 | u64 node_name = 0; | 1311 | u64 node_name = 0; |
1229 | struct lpfc_nodelist *ndlp = NULL; | 1312 | struct lpfc_nodelist *ndlp = NULL; |
1230 | 1313 | ||
@@ -1245,7 +1328,7 @@ static void | |||
1245 | lpfc_get_starget_port_name(struct scsi_target *starget) | 1328 | lpfc_get_starget_port_name(struct scsi_target *starget) |
1246 | { | 1329 | { |
1247 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 1330 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
1248 | struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0]; | 1331 | struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; |
1249 | u64 port_name = 0; | 1332 | u64 port_name = 0; |
1250 | struct lpfc_nodelist *ndlp = NULL; | 1333 | struct lpfc_nodelist *ndlp = NULL; |
1251 | 1334 | ||
@@ -1366,6 +1449,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
1366 | lpfc_log_verbose_init(phba, lpfc_log_verbose); | 1449 | lpfc_log_verbose_init(phba, lpfc_log_verbose); |
1367 | lpfc_cr_delay_init(phba, lpfc_cr_delay); | 1450 | lpfc_cr_delay_init(phba, lpfc_cr_delay); |
1368 | lpfc_cr_count_init(phba, lpfc_cr_count); | 1451 | lpfc_cr_count_init(phba, lpfc_cr_count); |
1452 | lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support); | ||
1369 | lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth); | 1453 | lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth); |
1370 | lpfc_fcp_class_init(phba, lpfc_fcp_class); | 1454 | lpfc_fcp_class_init(phba, lpfc_fcp_class); |
1371 | lpfc_use_adisc_init(phba, lpfc_use_adisc); | 1455 | lpfc_use_adisc_init(phba, lpfc_use_adisc); |
@@ -1411,5 +1495,9 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
1411 | default: | 1495 | default: |
1412 | phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH; | 1496 | phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH; |
1413 | } | 1497 | } |
1498 | |||
1499 | if (phba->cfg_hba_queue_depth > lpfc_hba_queue_depth) | ||
1500 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); | ||
1501 | |||
1414 | return; | 1502 | return; |
1415 | } | 1503 | } |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index f1e708946e66..fad607b2e6f4 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -26,6 +26,7 @@ void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *); | |||
26 | void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); | 26 | void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); |
27 | int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *); | 27 | int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *); |
28 | void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *); | 28 | void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *); |
29 | void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *); | ||
29 | void lpfc_set_slim(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); | 30 | void lpfc_set_slim(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); |
30 | int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *, | 31 | int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *, |
31 | uint32_t); | 32 | uint32_t); |
@@ -42,9 +43,6 @@ void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | |||
42 | void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 43 | void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
43 | void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 44 | void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
44 | void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 45 | void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
45 | int lpfc_nlp_plogi(struct lpfc_hba *, struct lpfc_nodelist *); | ||
46 | int lpfc_nlp_adisc(struct lpfc_hba *, struct lpfc_nodelist *); | ||
47 | int lpfc_nlp_unmapped(struct lpfc_hba *, struct lpfc_nodelist *); | ||
48 | int lpfc_nlp_list(struct lpfc_hba *, struct lpfc_nodelist *, int); | 46 | int lpfc_nlp_list(struct lpfc_hba *, struct lpfc_nodelist *, int); |
49 | void lpfc_set_disctmo(struct lpfc_hba *); | 47 | void lpfc_set_disctmo(struct lpfc_hba *); |
50 | int lpfc_can_disctmo(struct lpfc_hba *); | 48 | int lpfc_can_disctmo(struct lpfc_hba *); |
@@ -54,12 +52,10 @@ int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, | |||
54 | int lpfc_nlp_remove(struct lpfc_hba *, struct lpfc_nodelist *); | 52 | int lpfc_nlp_remove(struct lpfc_hba *, struct lpfc_nodelist *); |
55 | void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t); | 53 | void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t); |
56 | struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t); | 54 | struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t); |
57 | struct lpfc_nodelist *lpfc_setup_rscn_node(struct lpfc_hba *, uint32_t); | ||
58 | void lpfc_disc_list_loopmap(struct lpfc_hba *); | 55 | void lpfc_disc_list_loopmap(struct lpfc_hba *); |
59 | void lpfc_disc_start(struct lpfc_hba *); | 56 | void lpfc_disc_start(struct lpfc_hba *); |
60 | void lpfc_disc_flush_list(struct lpfc_hba *); | 57 | void lpfc_disc_flush_list(struct lpfc_hba *); |
61 | void lpfc_disc_timeout(unsigned long); | 58 | void lpfc_disc_timeout(unsigned long); |
62 | void lpfc_scan_timeout(unsigned long); | ||
63 | 59 | ||
64 | struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi); | 60 | struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi); |
65 | 61 | ||
@@ -68,19 +64,13 @@ int lpfc_do_work(void *); | |||
68 | int lpfc_disc_state_machine(struct lpfc_hba *, struct lpfc_nodelist *, void *, | 64 | int lpfc_disc_state_machine(struct lpfc_hba *, struct lpfc_nodelist *, void *, |
69 | uint32_t); | 65 | uint32_t); |
70 | 66 | ||
71 | uint32_t lpfc_cmpl_prli_reglogin_issue(struct lpfc_hba *, | ||
72 | struct lpfc_nodelist *, void *, | ||
73 | uint32_t); | ||
74 | uint32_t lpfc_cmpl_plogi_prli_issue(struct lpfc_hba *, struct lpfc_nodelist *, | ||
75 | void *, uint32_t); | ||
76 | |||
77 | int lpfc_check_sparm(struct lpfc_hba *, struct lpfc_nodelist *, | 67 | int lpfc_check_sparm(struct lpfc_hba *, struct lpfc_nodelist *, |
78 | struct serv_parm *, uint32_t); | 68 | struct serv_parm *, uint32_t); |
79 | int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp, | 69 | int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp, |
80 | int); | 70 | int); |
81 | int lpfc_els_abort_flogi(struct lpfc_hba *); | 71 | int lpfc_els_abort_flogi(struct lpfc_hba *); |
82 | int lpfc_initial_flogi(struct lpfc_hba *); | 72 | int lpfc_initial_flogi(struct lpfc_hba *); |
83 | int lpfc_issue_els_plogi(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); | 73 | int lpfc_issue_els_plogi(struct lpfc_hba *, uint32_t, uint8_t); |
84 | int lpfc_issue_els_prli(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); | 74 | int lpfc_issue_els_prli(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); |
85 | int lpfc_issue_els_adisc(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); | 75 | int lpfc_issue_els_adisc(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); |
86 | int lpfc_issue_els_logo(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); | 76 | int lpfc_issue_els_logo(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t); |
@@ -94,6 +84,7 @@ int lpfc_els_rsp_adisc_acc(struct lpfc_hba *, struct lpfc_iocbq *, | |||
94 | struct lpfc_nodelist *); | 84 | struct lpfc_nodelist *); |
95 | int lpfc_els_rsp_prli_acc(struct lpfc_hba *, struct lpfc_iocbq *, | 85 | int lpfc_els_rsp_prli_acc(struct lpfc_hba *, struct lpfc_iocbq *, |
96 | struct lpfc_nodelist *); | 86 | struct lpfc_nodelist *); |
87 | void lpfc_cancel_retry_delay_tmo(struct lpfc_hba *, struct lpfc_nodelist *); | ||
97 | void lpfc_els_retry_delay(unsigned long); | 88 | void lpfc_els_retry_delay(unsigned long); |
98 | void lpfc_els_retry_delay_handler(struct lpfc_nodelist *); | 89 | void lpfc_els_retry_delay_handler(struct lpfc_nodelist *); |
99 | void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, | 90 | void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, |
@@ -117,18 +108,15 @@ void lpfc_fdmi_tmo_handler(struct lpfc_hba *); | |||
117 | int lpfc_config_port_prep(struct lpfc_hba *); | 108 | int lpfc_config_port_prep(struct lpfc_hba *); |
118 | int lpfc_config_port_post(struct lpfc_hba *); | 109 | int lpfc_config_port_post(struct lpfc_hba *); |
119 | int lpfc_hba_down_prep(struct lpfc_hba *); | 110 | int lpfc_hba_down_prep(struct lpfc_hba *); |
111 | int lpfc_hba_down_post(struct lpfc_hba *); | ||
120 | void lpfc_hba_init(struct lpfc_hba *, uint32_t *); | 112 | void lpfc_hba_init(struct lpfc_hba *, uint32_t *); |
121 | int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int); | 113 | int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int); |
122 | void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); | 114 | void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); |
123 | uint8_t *lpfc_get_lpfchba_info(struct lpfc_hba *, uint8_t *); | ||
124 | int lpfc_fcp_abort(struct lpfc_hba *, int, int, int); | ||
125 | int lpfc_online(struct lpfc_hba *); | 115 | int lpfc_online(struct lpfc_hba *); |
126 | int lpfc_offline(struct lpfc_hba *); | 116 | int lpfc_offline(struct lpfc_hba *); |
127 | 117 | ||
128 | |||
129 | int lpfc_sli_setup(struct lpfc_hba *); | 118 | int lpfc_sli_setup(struct lpfc_hba *); |
130 | int lpfc_sli_queue_setup(struct lpfc_hba *); | 119 | int lpfc_sli_queue_setup(struct lpfc_hba *); |
131 | void lpfc_slim_access(struct lpfc_hba *); | ||
132 | 120 | ||
133 | void lpfc_handle_eratt(struct lpfc_hba *); | 121 | void lpfc_handle_eratt(struct lpfc_hba *); |
134 | void lpfc_handle_latt(struct lpfc_hba *); | 122 | void lpfc_handle_latt(struct lpfc_hba *); |
@@ -137,6 +125,7 @@ irqreturn_t lpfc_intr_handler(int, void *, struct pt_regs *); | |||
137 | void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *); | 125 | void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *); |
138 | void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *); | 126 | void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *); |
139 | void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *); | 127 | void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *); |
128 | void lpfc_kill_board(struct lpfc_hba *, LPFC_MBOXQ_t *); | ||
140 | void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *); | 129 | void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *); |
141 | LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *); | 130 | LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *); |
142 | 131 | ||
@@ -149,6 +138,12 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba); | |||
149 | struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); | 138 | struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); |
150 | void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); | 139 | void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); |
151 | uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); | 140 | uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); |
141 | |||
142 | void lpfc_reset_barrier(struct lpfc_hba * phba); | ||
143 | int lpfc_sli_brdready(struct lpfc_hba *, uint32_t); | ||
144 | int lpfc_sli_brdkill(struct lpfc_hba *); | ||
145 | int lpfc_sli_brdreset(struct lpfc_hba *); | ||
146 | int lpfc_sli_brdrestart(struct lpfc_hba *); | ||
152 | int lpfc_sli_hba_setup(struct lpfc_hba *); | 147 | int lpfc_sli_hba_setup(struct lpfc_hba *); |
153 | int lpfc_sli_hba_down(struct lpfc_hba *); | 148 | int lpfc_sli_hba_down(struct lpfc_hba *); |
154 | int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); | 149 | int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); |
@@ -174,12 +169,10 @@ int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, | |||
174 | 169 | ||
175 | void lpfc_mbox_timeout(unsigned long); | 170 | void lpfc_mbox_timeout(unsigned long); |
176 | void lpfc_mbox_timeout_handler(struct lpfc_hba *); | 171 | void lpfc_mbox_timeout_handler(struct lpfc_hba *); |
177 | void lpfc_map_fcp_cmnd_to_bpl(struct lpfc_hba *, struct lpfc_scsi_buf *); | ||
178 | void lpfc_free_scsi_cmd(struct lpfc_scsi_buf *); | ||
179 | uint32_t lpfc_os_timeout_transform(struct lpfc_hba *, uint32_t); | ||
180 | 172 | ||
181 | struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, | 173 | struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba *, uint32_t, uint32_t); |
182 | uint32_t did); | 174 | struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_hba *, uint32_t, |
175 | struct lpfc_name *); | ||
183 | 176 | ||
184 | int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | 177 | int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, |
185 | uint32_t timeout); | 178 | uint32_t timeout); |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 7f427f9c4688..b65ee57af53e 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -260,8 +260,10 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, | |||
260 | icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL; | 260 | icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL; |
261 | icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP; | 261 | icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP; |
262 | 262 | ||
263 | if (!tmo) | 263 | if (!tmo) { |
264 | tmo = (2 * phba->fc_ratov) + 1; | 264 | /* FC spec states we need 3 * ratov for CT requests */ |
265 | tmo = (3 * phba->fc_ratov); | ||
266 | } | ||
265 | icmd->ulpTimeout = tmo; | 267 | icmd->ulpTimeout = tmo; |
266 | icmd->ulpBdeCount = 1; | 268 | icmd->ulpBdeCount = 1; |
267 | icmd->ulpLe = 1; | 269 | icmd->ulpLe = 1; |
@@ -321,6 +323,7 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) | |||
321 | struct lpfc_sli_ct_request *Response = | 323 | struct lpfc_sli_ct_request *Response = |
322 | (struct lpfc_sli_ct_request *) mp->virt; | 324 | (struct lpfc_sli_ct_request *) mp->virt; |
323 | struct lpfc_nodelist *ndlp = NULL; | 325 | struct lpfc_nodelist *ndlp = NULL; |
326 | struct lpfc_nodelist *next_ndlp; | ||
324 | struct lpfc_dmabuf *mlast, *next_mp; | 327 | struct lpfc_dmabuf *mlast, *next_mp; |
325 | uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; | 328 | uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; |
326 | uint32_t Did; | 329 | uint32_t Did; |
@@ -389,8 +392,36 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) | |||
389 | nsout1: | 392 | nsout1: |
390 | list_del(&head); | 393 | list_del(&head); |
391 | 394 | ||
392 | /* Here we are finished in the case RSCN */ | 395 | /* |
396 | * The driver has cycled through all Nports in the RSCN payload. | ||
397 | * Complete the handling by cleaning up and marking the | ||
398 | * current driver state. | ||
399 | */ | ||
393 | if (phba->hba_state == LPFC_HBA_READY) { | 400 | if (phba->hba_state == LPFC_HBA_READY) { |
401 | |||
402 | /* | ||
403 | * Switch ports that connect a loop of multiple targets need | ||
404 | * special consideration. The driver wants to unregister the | ||
405 | * rpi only on the target that was pulled from the loop. On | ||
406 | * RSCN, the driver wants to rediscover an NPort only if the | ||
407 | * driver flagged it as NLP_NPR_2B_DISC. Provided adisc is | ||
408 | * not enabled and the NPort is not capable of retransmissions | ||
409 | * (FC Tape) prevent timing races with the scsi error handler by | ||
410 | * unregistering the Nport's RPI. This action causes all | ||
411 | * outstanding IO to flush back to the midlayer. | ||
412 | */ | ||
413 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, | ||
414 | nlp_listp) { | ||
415 | if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC) && | ||
416 | (lpfc_rscn_payload_check(phba, ndlp->nlp_DID))) { | ||
417 | if ((phba->cfg_use_adisc == 0) && | ||
418 | !(ndlp->nlp_fcp_info & | ||
419 | NLP_FCP_2_DEVICE)) { | ||
420 | lpfc_unreg_rpi(phba, ndlp); | ||
421 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | ||
422 | } | ||
423 | } | ||
424 | } | ||
394 | lpfc_els_flush_rscn(phba); | 425 | lpfc_els_flush_rscn(phba); |
395 | spin_lock_irq(phba->host->host_lock); | 426 | spin_lock_irq(phba->host->host_lock); |
396 | phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */ | 427 | phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */ |
@@ -449,6 +480,11 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
449 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | 480 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; |
450 | if (CTrsp->CommandResponse.bits.CmdRsp == | 481 | if (CTrsp->CommandResponse.bits.CmdRsp == |
451 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { | 482 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { |
483 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | ||
484 | "%d:0239 NameServer Rsp " | ||
485 | "Data: x%x\n", | ||
486 | phba->brd_no, | ||
487 | phba->fc_flag); | ||
452 | lpfc_ns_rsp(phba, outp, | 488 | lpfc_ns_rsp(phba, outp, |
453 | (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); | 489 | (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); |
454 | } else if (CTrsp->CommandResponse.bits.CmdRsp == | 490 | } else if (CTrsp->CommandResponse.bits.CmdRsp == |
@@ -978,19 +1014,19 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
978 | ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); | 1014 | ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); |
979 | ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED); | 1015 | ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED); |
980 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); | 1016 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); |
981 | if (FC_JEDEC_ID(vp->rev.biuRev) == VIPER_JEDEC_ID) | 1017 | |
1018 | ae->un.SupportSpeed = 0; | ||
1019 | if (phba->lmt & LMT_10Gb) | ||
982 | ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT; | 1020 | ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT; |
983 | else if (FC_JEDEC_ID(vp->rev.biuRev) == HELIOS_JEDEC_ID) | 1021 | if (phba->lmt & LMT_8Gb) |
984 | ae->un.SupportSpeed = HBA_PORTSPEED_4GBIT; | 1022 | ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT; |
985 | else if ((FC_JEDEC_ID(vp->rev.biuRev) == | 1023 | if (phba->lmt & LMT_4Gb) |
986 | CENTAUR_2G_JEDEC_ID) | 1024 | ae->un.SupportSpeed |= HBA_PORTSPEED_4GBIT; |
987 | || (FC_JEDEC_ID(vp->rev.biuRev) == | 1025 | if (phba->lmt & LMT_2Gb) |
988 | PEGASUS_JEDEC_ID) | 1026 | ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT; |
989 | || (FC_JEDEC_ID(vp->rev.biuRev) == | 1027 | if (phba->lmt & LMT_1Gb) |
990 | THOR_JEDEC_ID)) | 1028 | ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT; |
991 | ae->un.SupportSpeed = HBA_PORTSPEED_2GBIT; | 1029 | |
992 | else | ||
993 | ae->un.SupportSpeed = HBA_PORTSPEED_1GBIT; | ||
994 | pab->ab.EntryCnt++; | 1030 | pab->ab.EntryCnt++; |
995 | size += FOURBYTES + 4; | 1031 | size += FOURBYTES + 4; |
996 | 1032 | ||
@@ -1130,11 +1166,6 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba) | |||
1130 | { | 1166 | { |
1131 | struct lpfc_nodelist *ndlp; | 1167 | struct lpfc_nodelist *ndlp; |
1132 | 1168 | ||
1133 | spin_lock_irq(phba->host->host_lock); | ||
1134 | if (!(phba->work_hba_events & WORKER_FDMI_TMO)) { | ||
1135 | spin_unlock_irq(phba->host->host_lock); | ||
1136 | return; | ||
1137 | } | ||
1138 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID); | 1169 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID); |
1139 | if (ndlp) { | 1170 | if (ndlp) { |
1140 | if (system_utsname.nodename[0] != '\0') { | 1171 | if (system_utsname.nodename[0] != '\0') { |
@@ -1143,7 +1174,6 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba) | |||
1143 | mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); | 1174 | mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); |
1144 | } | 1175 | } |
1145 | } | 1176 | } |
1146 | spin_unlock_irq(phba->host->host_lock); | ||
1147 | return; | 1177 | return; |
1148 | } | 1178 | } |
1149 | 1179 | ||
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index ed6c81660e03..8932b1be2b60 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -28,18 +28,24 @@ | |||
28 | * This is used by Fibre Channel protocol to support FCP. | 28 | * This is used by Fibre Channel protocol to support FCP. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | /* worker thread events */ | ||
32 | enum lpfc_work_type { | ||
33 | LPFC_EVT_NODEV_TMO, | ||
34 | LPFC_EVT_ONLINE, | ||
35 | LPFC_EVT_OFFLINE, | ||
36 | LPFC_EVT_WARM_START, | ||
37 | LPFC_EVT_KILL, | ||
38 | LPFC_EVT_ELS_RETRY, | ||
39 | }; | ||
40 | |||
31 | /* structure used to queue event to the discovery tasklet */ | 41 | /* structure used to queue event to the discovery tasklet */ |
32 | struct lpfc_work_evt { | 42 | struct lpfc_work_evt { |
33 | struct list_head evt_listp; | 43 | struct list_head evt_listp; |
34 | void * evt_arg1; | 44 | void * evt_arg1; |
35 | void * evt_arg2; | 45 | void * evt_arg2; |
36 | uint32_t evt; | 46 | enum lpfc_work_type evt; |
37 | }; | 47 | }; |
38 | 48 | ||
39 | #define LPFC_EVT_NODEV_TMO 0x1 | ||
40 | #define LPFC_EVT_ONLINE 0x2 | ||
41 | #define LPFC_EVT_OFFLINE 0x3 | ||
42 | #define LPFC_EVT_ELS_RETRY 0x4 | ||
43 | 49 | ||
44 | struct lpfc_nodelist { | 50 | struct lpfc_nodelist { |
45 | struct list_head nlp_listp; | 51 | struct list_head nlp_listp; |
@@ -56,6 +62,7 @@ struct lpfc_nodelist { | |||
56 | 62 | ||
57 | uint16_t nlp_rpi; | 63 | uint16_t nlp_rpi; |
58 | uint16_t nlp_state; /* state transition indicator */ | 64 | uint16_t nlp_state; /* state transition indicator */ |
65 | uint16_t nlp_prev_state; /* state transition indicator */ | ||
59 | uint16_t nlp_xri; /* output exchange id for RPI */ | 66 | uint16_t nlp_xri; /* output exchange id for RPI */ |
60 | uint16_t nlp_sid; /* scsi id */ | 67 | uint16_t nlp_sid; /* scsi id */ |
61 | #define NLP_NO_SID 0xffff | 68 | #define NLP_NO_SID 0xffff |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 20f1a0713db2..4813beaaca8f 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -92,15 +92,14 @@ lpfc_els_chk_latt(struct lpfc_hba * phba) | |||
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
95 | return (1); | 95 | return 1; |
96 | 96 | ||
97 | } | 97 | } |
98 | 98 | ||
99 | static struct lpfc_iocbq * | 99 | static struct lpfc_iocbq * |
100 | lpfc_prep_els_iocb(struct lpfc_hba * phba, | 100 | lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, |
101 | uint8_t expectRsp, | 101 | uint16_t cmdSize, uint8_t retry, struct lpfc_nodelist * ndlp, |
102 | uint16_t cmdSize, | 102 | uint32_t did, uint32_t elscmd) |
103 | uint8_t retry, struct lpfc_nodelist * ndlp, uint32_t elscmd) | ||
104 | { | 103 | { |
105 | struct lpfc_sli_ring *pring; | 104 | struct lpfc_sli_ring *pring; |
106 | struct lpfc_iocbq *elsiocb; | 105 | struct lpfc_iocbq *elsiocb; |
@@ -181,7 +180,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, | |||
181 | icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL; | 180 | icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL; |
182 | if (expectRsp) { | 181 | if (expectRsp) { |
183 | icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); | 182 | icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); |
184 | icmd->un.elsreq64.remoteID = ndlp->nlp_DID; /* DID */ | 183 | icmd->un.elsreq64.remoteID = did; /* DID */ |
185 | icmd->ulpCommand = CMD_ELS_REQUEST64_CR; | 184 | icmd->ulpCommand = CMD_ELS_REQUEST64_CR; |
186 | } else { | 185 | } else { |
187 | icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64); | 186 | icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64); |
@@ -225,7 +224,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, | |||
225 | "%d:0116 Xmit ELS command x%x to remote " | 224 | "%d:0116 Xmit ELS command x%x to remote " |
226 | "NPORT x%x Data: x%x x%x\n", | 225 | "NPORT x%x Data: x%x x%x\n", |
227 | phba->brd_no, elscmd, | 226 | phba->brd_no, elscmd, |
228 | ndlp->nlp_DID, icmd->ulpIoTag, phba->hba_state); | 227 | did, icmd->ulpIoTag, phba->hba_state); |
229 | } else { | 228 | } else { |
230 | /* Xmit ELS response <elsCmd> to remote NPORT <did> */ | 229 | /* Xmit ELS response <elsCmd> to remote NPORT <did> */ |
231 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 230 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -235,7 +234,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, | |||
235 | ndlp->nlp_DID, icmd->ulpIoTag, cmdSize); | 234 | ndlp->nlp_DID, icmd->ulpIoTag, cmdSize); |
236 | } | 235 | } |
237 | 236 | ||
238 | return (elsiocb); | 237 | return elsiocb; |
239 | } | 238 | } |
240 | 239 | ||
241 | 240 | ||
@@ -446,9 +445,10 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, | |||
446 | lpfc_printf_log(phba, | 445 | lpfc_printf_log(phba, |
447 | KERN_INFO, | 446 | KERN_INFO, |
448 | LOG_ELS, | 447 | LOG_ELS, |
449 | "%d:0100 FLOGI failure Data: x%x x%x\n", | 448 | "%d:0100 FLOGI failure Data: x%x x%x x%x\n", |
450 | phba->brd_no, | 449 | phba->brd_no, |
451 | irsp->ulpStatus, irsp->un.ulpWord[4]); | 450 | irsp->ulpStatus, irsp->un.ulpWord[4], |
451 | irsp->ulpTimeout); | ||
452 | goto flogifail; | 452 | goto flogifail; |
453 | } | 453 | } |
454 | 454 | ||
@@ -515,10 +515,10 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
515 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 515 | pring = &phba->sli.ring[LPFC_ELS_RING]; |
516 | 516 | ||
517 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); | 517 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); |
518 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 518 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
519 | ndlp, ELS_CMD_FLOGI)) == 0) { | 519 | ndlp->nlp_DID, ELS_CMD_FLOGI); |
520 | return (1); | 520 | if (!elsiocb) |
521 | } | 521 | return 1; |
522 | 522 | ||
523 | icmd = &elsiocb->iocb; | 523 | icmd = &elsiocb->iocb; |
524 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 524 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -552,9 +552,9 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
552 | spin_unlock_irq(phba->host->host_lock); | 552 | spin_unlock_irq(phba->host->host_lock); |
553 | if (rc == IOCB_ERROR) { | 553 | if (rc == IOCB_ERROR) { |
554 | lpfc_els_free_iocb(phba, elsiocb); | 554 | lpfc_els_free_iocb(phba, elsiocb); |
555 | return (1); | 555 | return 1; |
556 | } | 556 | } |
557 | return (0); | 557 | return 0; |
558 | } | 558 | } |
559 | 559 | ||
560 | int | 560 | int |
@@ -611,29 +611,21 @@ lpfc_initial_flogi(struct lpfc_hba * phba) | |||
611 | { | 611 | { |
612 | struct lpfc_nodelist *ndlp; | 612 | struct lpfc_nodelist *ndlp; |
613 | 613 | ||
614 | /* First look for Fabric ndlp on the unmapped list */ | 614 | /* First look for the Fabric ndlp */ |
615 | 615 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, Fabric_DID); | |
616 | if ((ndlp = | 616 | if (!ndlp) { |
617 | lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, | ||
618 | Fabric_DID)) == 0) { | ||
619 | /* Cannot find existing Fabric ndlp, so allocate a new one */ | 617 | /* Cannot find existing Fabric ndlp, so allocate a new one */ |
620 | if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) | 618 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
621 | == 0) { | 619 | if (!ndlp) |
622 | return (0); | 620 | return 0; |
623 | } | ||
624 | lpfc_nlp_init(phba, ndlp, Fabric_DID); | 621 | lpfc_nlp_init(phba, ndlp, Fabric_DID); |
625 | } | 622 | } else { |
626 | else { | 623 | lpfc_nlp_list(phba, ndlp, NLP_JUST_DQ); |
627 | phba->fc_unmap_cnt--; | ||
628 | list_del(&ndlp->nlp_listp); | ||
629 | spin_lock_irq(phba->host->host_lock); | ||
630 | ndlp->nlp_flag &= ~NLP_LIST_MASK; | ||
631 | spin_unlock_irq(phba->host->host_lock); | ||
632 | } | 624 | } |
633 | if (lpfc_issue_els_flogi(phba, ndlp, 0)) { | 625 | if (lpfc_issue_els_flogi(phba, ndlp, 0)) { |
634 | mempool_free( ndlp, phba->nlp_mem_pool); | 626 | mempool_free( ndlp, phba->nlp_mem_pool); |
635 | } | 627 | } |
636 | return (1); | 628 | return 1; |
637 | } | 629 | } |
638 | 630 | ||
639 | static void | 631 | static void |
@@ -659,38 +651,90 @@ lpfc_more_plogi(struct lpfc_hba * phba) | |||
659 | return; | 651 | return; |
660 | } | 652 | } |
661 | 653 | ||
654 | static struct lpfc_nodelist * | ||
655 | lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | ||
656 | struct lpfc_nodelist *ndlp) | ||
657 | { | ||
658 | struct lpfc_nodelist *new_ndlp; | ||
659 | struct lpfc_dmabuf *pcmd, *prsp; | ||
660 | uint32_t *lp; | ||
661 | struct serv_parm *sp; | ||
662 | uint8_t name[sizeof (struct lpfc_name)]; | ||
663 | uint32_t rc; | ||
664 | |||
665 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
666 | prsp = (struct lpfc_dmabuf *) pcmd->list.next; | ||
667 | lp = (uint32_t *) prsp->virt; | ||
668 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | ||
669 | |||
670 | /* Now we to find out if the NPort we are logging into, matches the WWPN | ||
671 | * we have for that ndlp. If not, we have some work to do. | ||
672 | */ | ||
673 | new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); | ||
674 | |||
675 | memset(name, 0, sizeof (struct lpfc_name)); | ||
676 | rc = memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); | ||
677 | if (!rc || (new_ndlp == ndlp)) { | ||
678 | return ndlp; | ||
679 | } | ||
680 | |||
681 | if (!new_ndlp) { | ||
682 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); | ||
683 | if (!new_ndlp) | ||
684 | return ndlp; | ||
685 | |||
686 | lpfc_nlp_init(phba, new_ndlp, ndlp->nlp_DID); | ||
687 | } | ||
688 | |||
689 | lpfc_unreg_rpi(phba, new_ndlp); | ||
690 | new_ndlp->nlp_prev_state = ndlp->nlp_state; | ||
691 | new_ndlp->nlp_DID = ndlp->nlp_DID; | ||
692 | new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | ||
693 | lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST); | ||
694 | |||
695 | /* Move this back to NPR list */ | ||
696 | lpfc_unreg_rpi(phba, ndlp); | ||
697 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | ||
698 | ndlp->nlp_state = NLP_STE_NPR_NODE; | ||
699 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | ||
700 | |||
701 | return new_ndlp; | ||
702 | } | ||
703 | |||
662 | static void | 704 | static void |
663 | lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 705 | lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, |
664 | struct lpfc_iocbq * rspiocb) | 706 | struct lpfc_iocbq * rspiocb) |
665 | { | 707 | { |
666 | IOCB_t *irsp; | 708 | IOCB_t *irsp; |
667 | struct lpfc_sli *psli; | ||
668 | struct lpfc_nodelist *ndlp; | 709 | struct lpfc_nodelist *ndlp; |
669 | int disc, rc, did, type; | 710 | int disc, rc, did, type; |
670 | 711 | ||
671 | psli = &phba->sli; | ||
672 | 712 | ||
673 | /* we pass cmdiocb to state machine which needs rspiocb as well */ | 713 | /* we pass cmdiocb to state machine which needs rspiocb as well */ |
674 | cmdiocb->context_un.rsp_iocb = rspiocb; | 714 | cmdiocb->context_un.rsp_iocb = rspiocb; |
675 | 715 | ||
676 | irsp = &rspiocb->iocb; | 716 | irsp = &rspiocb->iocb; |
677 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 717 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, |
678 | spin_lock_irq(phba->host->host_lock); | 718 | irsp->un.elsreq64.remoteID); |
679 | ndlp->nlp_flag &= ~NLP_PLOGI_SND; | 719 | if (!ndlp) |
680 | spin_unlock_irq(phba->host->host_lock); | 720 | goto out; |
681 | 721 | ||
682 | /* Since ndlp can be freed in the disc state machine, note if this node | 722 | /* Since ndlp can be freed in the disc state machine, note if this node |
683 | * is being used during discovery. | 723 | * is being used during discovery. |
684 | */ | 724 | */ |
685 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); | 725 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); |
726 | spin_lock_irq(phba->host->host_lock); | ||
727 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | ||
728 | spin_unlock_irq(phba->host->host_lock); | ||
686 | rc = 0; | 729 | rc = 0; |
687 | 730 | ||
688 | /* PLOGI completes to NPort <nlp_DID> */ | 731 | /* PLOGI completes to NPort <nlp_DID> */ |
689 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 732 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
690 | "%d:0102 PLOGI completes to NPort x%x " | 733 | "%d:0102 PLOGI completes to NPort x%x " |
691 | "Data: x%x x%x x%x x%x\n", | 734 | "Data: x%x x%x x%x x%x x%x\n", |
692 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, | 735 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, |
693 | irsp->un.ulpWord[4], disc, phba->num_disc_nodes); | 736 | irsp->un.ulpWord[4], irsp->ulpTimeout, disc, |
737 | phba->num_disc_nodes); | ||
694 | 738 | ||
695 | /* Check to see if link went down during discovery */ | 739 | /* Check to see if link went down during discovery */ |
696 | if (lpfc_els_chk_latt(phba)) { | 740 | if (lpfc_els_chk_latt(phba)) { |
@@ -722,43 +766,28 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
722 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || | 766 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || |
723 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | 767 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || |
724 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { | 768 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { |
725 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); | 769 | rc = NLP_STE_FREED_NODE; |
726 | } | 770 | } else { |
727 | else { | ||
728 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 771 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, |
729 | NLP_EVT_CMPL_PLOGI); | 772 | NLP_EVT_CMPL_PLOGI); |
730 | } | 773 | } |
731 | } else { | 774 | } else { |
732 | /* Good status, call state machine */ | 775 | /* Good status, call state machine */ |
776 | ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp); | ||
733 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 777 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, |
734 | NLP_EVT_CMPL_PLOGI); | 778 | NLP_EVT_CMPL_PLOGI); |
735 | } | 779 | } |
736 | 780 | ||
737 | if (type & NLP_FABRIC) { | ||
738 | /* If we cannot login to Nameserver, kick off discovery now */ | ||
739 | if ((did == NameServer_DID) && (rc == NLP_STE_FREED_NODE)) { | ||
740 | lpfc_disc_start(phba); | ||
741 | } | ||
742 | goto out; | ||
743 | } | ||
744 | |||
745 | if (disc && phba->num_disc_nodes) { | 781 | if (disc && phba->num_disc_nodes) { |
746 | /* Check to see if there are more PLOGIs to be sent */ | 782 | /* Check to see if there are more PLOGIs to be sent */ |
747 | lpfc_more_plogi(phba); | 783 | lpfc_more_plogi(phba); |
748 | } | 784 | } |
749 | 785 | ||
750 | if (rc != NLP_STE_FREED_NODE) { | 786 | if (phba->num_disc_nodes == 0) { |
751 | spin_lock_irq(phba->host->host_lock); | 787 | spin_lock_irq(phba->host->host_lock); |
752 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 788 | phba->fc_flag &= ~FC_NDISC_ACTIVE; |
753 | spin_unlock_irq(phba->host->host_lock); | 789 | spin_unlock_irq(phba->host->host_lock); |
754 | } | ||
755 | 790 | ||
756 | if (phba->num_disc_nodes == 0) { | ||
757 | if(disc) { | ||
758 | spin_lock_irq(phba->host->host_lock); | ||
759 | phba->fc_flag &= ~FC_NDISC_ACTIVE; | ||
760 | spin_unlock_irq(phba->host->host_lock); | ||
761 | } | ||
762 | lpfc_can_disctmo(phba); | 791 | lpfc_can_disctmo(phba); |
763 | if (phba->fc_flag & FC_RSCN_MODE) { | 792 | if (phba->fc_flag & FC_RSCN_MODE) { |
764 | /* Check to see if more RSCNs came in while we were | 793 | /* Check to see if more RSCNs came in while we were |
@@ -781,8 +810,7 @@ out: | |||
781 | } | 810 | } |
782 | 811 | ||
783 | int | 812 | int |
784 | lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | 813 | lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) |
785 | uint8_t retry) | ||
786 | { | 814 | { |
787 | struct serv_parm *sp; | 815 | struct serv_parm *sp; |
788 | IOCB_t *icmd; | 816 | IOCB_t *icmd; |
@@ -796,10 +824,10 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
796 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 824 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
797 | 825 | ||
798 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); | 826 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); |
799 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 827 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, 0, did, |
800 | ndlp, ELS_CMD_PLOGI)) == 0) { | 828 | ELS_CMD_PLOGI); |
801 | return (1); | 829 | if (!elsiocb) |
802 | } | 830 | return 1; |
803 | 831 | ||
804 | icmd = &elsiocb->iocb; | 832 | icmd = &elsiocb->iocb; |
805 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 833 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -819,15 +847,13 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
819 | phba->fc_stat.elsXmitPLOGI++; | 847 | phba->fc_stat.elsXmitPLOGI++; |
820 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; | 848 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; |
821 | spin_lock_irq(phba->host->host_lock); | 849 | spin_lock_irq(phba->host->host_lock); |
822 | ndlp->nlp_flag |= NLP_PLOGI_SND; | ||
823 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 850 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
824 | ndlp->nlp_flag &= ~NLP_PLOGI_SND; | ||
825 | spin_unlock_irq(phba->host->host_lock); | 851 | spin_unlock_irq(phba->host->host_lock); |
826 | lpfc_els_free_iocb(phba, elsiocb); | 852 | lpfc_els_free_iocb(phba, elsiocb); |
827 | return (1); | 853 | return 1; |
828 | } | 854 | } |
829 | spin_unlock_irq(phba->host->host_lock); | 855 | spin_unlock_irq(phba->host->host_lock); |
830 | return (0); | 856 | return 0; |
831 | } | 857 | } |
832 | 858 | ||
833 | static void | 859 | static void |
@@ -851,9 +877,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
851 | /* PRLI completes to NPort <nlp_DID> */ | 877 | /* PRLI completes to NPort <nlp_DID> */ |
852 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 878 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
853 | "%d:0103 PRLI completes to NPort x%x " | 879 | "%d:0103 PRLI completes to NPort x%x " |
854 | "Data: x%x x%x x%x\n", | 880 | "Data: x%x x%x x%x x%x\n", |
855 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, | 881 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, |
856 | irsp->un.ulpWord[4], phba->num_disc_nodes); | 882 | irsp->un.ulpWord[4], irsp->ulpTimeout, |
883 | phba->num_disc_nodes); | ||
857 | 884 | ||
858 | phba->fc_prli_sent--; | 885 | phba->fc_prli_sent--; |
859 | /* Check to see if link went down during discovery */ | 886 | /* Check to see if link went down during discovery */ |
@@ -873,8 +900,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
873 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | 900 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || |
874 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { | 901 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { |
875 | goto out; | 902 | goto out; |
876 | } | 903 | } else { |
877 | else { | ||
878 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 904 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, |
879 | NLP_EVT_CMPL_PRLI); | 905 | NLP_EVT_CMPL_PRLI); |
880 | } | 906 | } |
@@ -904,10 +930,10 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
904 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 930 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
905 | 931 | ||
906 | cmdsize = (sizeof (uint32_t) + sizeof (PRLI)); | 932 | cmdsize = (sizeof (uint32_t) + sizeof (PRLI)); |
907 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 933 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
908 | ndlp, ELS_CMD_PRLI)) == 0) { | 934 | ndlp->nlp_DID, ELS_CMD_PRLI); |
909 | return (1); | 935 | if (!elsiocb) |
910 | } | 936 | return 1; |
911 | 937 | ||
912 | icmd = &elsiocb->iocb; | 938 | icmd = &elsiocb->iocb; |
913 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 939 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -943,11 +969,11 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
943 | ndlp->nlp_flag &= ~NLP_PRLI_SND; | 969 | ndlp->nlp_flag &= ~NLP_PRLI_SND; |
944 | spin_unlock_irq(phba->host->host_lock); | 970 | spin_unlock_irq(phba->host->host_lock); |
945 | lpfc_els_free_iocb(phba, elsiocb); | 971 | lpfc_els_free_iocb(phba, elsiocb); |
946 | return (1); | 972 | return 1; |
947 | } | 973 | } |
948 | spin_unlock_irq(phba->host->host_lock); | 974 | spin_unlock_irq(phba->host->host_lock); |
949 | phba->fc_prli_sent++; | 975 | phba->fc_prli_sent++; |
950 | return (0); | 976 | return 0; |
951 | } | 977 | } |
952 | 978 | ||
953 | static void | 979 | static void |
@@ -1016,21 +1042,22 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1016 | 1042 | ||
1017 | irsp = &(rspiocb->iocb); | 1043 | irsp = &(rspiocb->iocb); |
1018 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 1044 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
1019 | spin_lock_irq(phba->host->host_lock); | ||
1020 | ndlp->nlp_flag &= ~NLP_ADISC_SND; | ||
1021 | spin_unlock_irq(phba->host->host_lock); | ||
1022 | 1045 | ||
1023 | /* Since ndlp can be freed in the disc state machine, note if this node | 1046 | /* Since ndlp can be freed in the disc state machine, note if this node |
1024 | * is being used during discovery. | 1047 | * is being used during discovery. |
1025 | */ | 1048 | */ |
1026 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); | 1049 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); |
1050 | spin_lock_irq(phba->host->host_lock); | ||
1051 | ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC); | ||
1052 | spin_unlock_irq(phba->host->host_lock); | ||
1027 | 1053 | ||
1028 | /* ADISC completes to NPort <nlp_DID> */ | 1054 | /* ADISC completes to NPort <nlp_DID> */ |
1029 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1055 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
1030 | "%d:0104 ADISC completes to NPort x%x " | 1056 | "%d:0104 ADISC completes to NPort x%x " |
1031 | "Data: x%x x%x x%x x%x\n", | 1057 | "Data: x%x x%x x%x x%x x%x\n", |
1032 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, | 1058 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, |
1033 | irsp->un.ulpWord[4], disc, phba->num_disc_nodes); | 1059 | irsp->un.ulpWord[4], irsp->ulpTimeout, disc, |
1060 | phba->num_disc_nodes); | ||
1034 | 1061 | ||
1035 | /* Check to see if link went down during discovery */ | 1062 | /* Check to see if link went down during discovery */ |
1036 | if (lpfc_els_chk_latt(phba)) { | 1063 | if (lpfc_els_chk_latt(phba)) { |
@@ -1054,13 +1081,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1054 | } | 1081 | } |
1055 | /* ADISC failed */ | 1082 | /* ADISC failed */ |
1056 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1083 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1057 | if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && | 1084 | if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || |
1058 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || | 1085 | ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) && |
1059 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | 1086 | (irsp->un.ulpWord[4] != IOERR_LINK_DOWN) && |
1060 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { | 1087 | (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) { |
1061 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); | ||
1062 | } | ||
1063 | else { | ||
1064 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 1088 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, |
1065 | NLP_EVT_CMPL_ADISC); | 1089 | NLP_EVT_CMPL_ADISC); |
1066 | } | 1090 | } |
@@ -1112,9 +1136,6 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1112 | } | 1136 | } |
1113 | } | 1137 | } |
1114 | } | 1138 | } |
1115 | spin_lock_irq(phba->host->host_lock); | ||
1116 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | ||
1117 | spin_unlock_irq(phba->host->host_lock); | ||
1118 | out: | 1139 | out: |
1119 | lpfc_els_free_iocb(phba, cmdiocb); | 1140 | lpfc_els_free_iocb(phba, cmdiocb); |
1120 | return; | 1141 | return; |
@@ -1136,10 +1157,10 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
1136 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 1157 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1137 | 1158 | ||
1138 | cmdsize = (sizeof (uint32_t) + sizeof (ADISC)); | 1159 | cmdsize = (sizeof (uint32_t) + sizeof (ADISC)); |
1139 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 1160 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
1140 | ndlp, ELS_CMD_ADISC)) == 0) { | 1161 | ndlp->nlp_DID, ELS_CMD_ADISC); |
1141 | return (1); | 1162 | if (!elsiocb) |
1142 | } | 1163 | return 1; |
1143 | 1164 | ||
1144 | icmd = &elsiocb->iocb; | 1165 | icmd = &elsiocb->iocb; |
1145 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 1166 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -1163,10 +1184,10 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
1163 | ndlp->nlp_flag &= ~NLP_ADISC_SND; | 1184 | ndlp->nlp_flag &= ~NLP_ADISC_SND; |
1164 | spin_unlock_irq(phba->host->host_lock); | 1185 | spin_unlock_irq(phba->host->host_lock); |
1165 | lpfc_els_free_iocb(phba, elsiocb); | 1186 | lpfc_els_free_iocb(phba, elsiocb); |
1166 | return (1); | 1187 | return 1; |
1167 | } | 1188 | } |
1168 | spin_unlock_irq(phba->host->host_lock); | 1189 | spin_unlock_irq(phba->host->host_lock); |
1169 | return (0); | 1190 | return 0; |
1170 | } | 1191 | } |
1171 | 1192 | ||
1172 | static void | 1193 | static void |
@@ -1190,9 +1211,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1190 | /* LOGO completes to NPort <nlp_DID> */ | 1211 | /* LOGO completes to NPort <nlp_DID> */ |
1191 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1212 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
1192 | "%d:0105 LOGO completes to NPort x%x " | 1213 | "%d:0105 LOGO completes to NPort x%x " |
1193 | "Data: x%x x%x x%x\n", | 1214 | "Data: x%x x%x x%x x%x\n", |
1194 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, | 1215 | phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, |
1195 | irsp->un.ulpWord[4], phba->num_disc_nodes); | 1216 | irsp->un.ulpWord[4], irsp->ulpTimeout, |
1217 | phba->num_disc_nodes); | ||
1196 | 1218 | ||
1197 | /* Check to see if link went down during discovery */ | 1219 | /* Check to see if link went down during discovery */ |
1198 | if (lpfc_els_chk_latt(phba)) | 1220 | if (lpfc_els_chk_latt(phba)) |
@@ -1211,18 +1233,15 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1211 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | 1233 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || |
1212 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { | 1234 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { |
1213 | goto out; | 1235 | goto out; |
1214 | } | 1236 | } else { |
1215 | else { | ||
1216 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 1237 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, |
1217 | NLP_EVT_CMPL_LOGO); | 1238 | NLP_EVT_CMPL_LOGO); |
1218 | } | 1239 | } |
1219 | } else { | 1240 | } else { |
1220 | /* Good status, call state machine */ | 1241 | /* Good status, call state machine. |
1242 | * This will unregister the rpi if needed. | ||
1243 | */ | ||
1221 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); | 1244 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); |
1222 | |||
1223 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | ||
1224 | lpfc_unreg_rpi(phba, ndlp); | ||
1225 | } | ||
1226 | } | 1245 | } |
1227 | 1246 | ||
1228 | out: | 1247 | out: |
@@ -1245,10 +1264,10 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
1245 | pring = &psli->ring[LPFC_ELS_RING]; | 1264 | pring = &psli->ring[LPFC_ELS_RING]; |
1246 | 1265 | ||
1247 | cmdsize = 2 * (sizeof (uint32_t) + sizeof (struct lpfc_name)); | 1266 | cmdsize = 2 * (sizeof (uint32_t) + sizeof (struct lpfc_name)); |
1248 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 1267 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
1249 | ndlp, ELS_CMD_LOGO)) == 0) { | 1268 | ndlp->nlp_DID, ELS_CMD_LOGO); |
1250 | return (1); | 1269 | if (!elsiocb) |
1251 | } | 1270 | return 1; |
1252 | 1271 | ||
1253 | icmd = &elsiocb->iocb; | 1272 | icmd = &elsiocb->iocb; |
1254 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 1273 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -1268,10 +1287,10 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
1268 | ndlp->nlp_flag &= ~NLP_LOGO_SND; | 1287 | ndlp->nlp_flag &= ~NLP_LOGO_SND; |
1269 | spin_unlock_irq(phba->host->host_lock); | 1288 | spin_unlock_irq(phba->host->host_lock); |
1270 | lpfc_els_free_iocb(phba, elsiocb); | 1289 | lpfc_els_free_iocb(phba, elsiocb); |
1271 | return (1); | 1290 | return 1; |
1272 | } | 1291 | } |
1273 | spin_unlock_irq(phba->host->host_lock); | 1292 | spin_unlock_irq(phba->host->host_lock); |
1274 | return (0); | 1293 | return 0; |
1275 | } | 1294 | } |
1276 | 1295 | ||
1277 | static void | 1296 | static void |
@@ -1286,9 +1305,10 @@ lpfc_cmpl_els_cmd(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1286 | lpfc_printf_log(phba, | 1305 | lpfc_printf_log(phba, |
1287 | KERN_INFO, | 1306 | KERN_INFO, |
1288 | LOG_ELS, | 1307 | LOG_ELS, |
1289 | "%d:0106 ELS cmd tag x%x completes Data: x%x x%x\n", | 1308 | "%d:0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n", |
1290 | phba->brd_no, | 1309 | phba->brd_no, |
1291 | irsp->ulpIoTag, irsp->ulpStatus, irsp->un.ulpWord[4]); | 1310 | irsp->ulpIoTag, irsp->ulpStatus, |
1311 | irsp->un.ulpWord[4], irsp->ulpTimeout); | ||
1292 | 1312 | ||
1293 | /* Check to see if link went down during discovery */ | 1313 | /* Check to see if link went down during discovery */ |
1294 | lpfc_els_chk_latt(phba); | 1314 | lpfc_els_chk_latt(phba); |
@@ -1310,16 +1330,17 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1310 | psli = &phba->sli; | 1330 | psli = &phba->sli; |
1311 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 1331 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1312 | cmdsize = (sizeof (uint32_t) + sizeof (SCR)); | 1332 | cmdsize = (sizeof (uint32_t) + sizeof (SCR)); |
1313 | if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) == 0) { | 1333 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
1314 | return (1); | 1334 | if (!ndlp) |
1315 | } | 1335 | return 1; |
1316 | 1336 | ||
1317 | lpfc_nlp_init(phba, ndlp, nportid); | 1337 | lpfc_nlp_init(phba, ndlp, nportid); |
1318 | 1338 | ||
1319 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 1339 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
1320 | ndlp, ELS_CMD_SCR)) == 0) { | 1340 | ndlp->nlp_DID, ELS_CMD_SCR); |
1341 | if (!elsiocb) { | ||
1321 | mempool_free( ndlp, phba->nlp_mem_pool); | 1342 | mempool_free( ndlp, phba->nlp_mem_pool); |
1322 | return (1); | 1343 | return 1; |
1323 | } | 1344 | } |
1324 | 1345 | ||
1325 | icmd = &elsiocb->iocb; | 1346 | icmd = &elsiocb->iocb; |
@@ -1339,11 +1360,11 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1339 | spin_unlock_irq(phba->host->host_lock); | 1360 | spin_unlock_irq(phba->host->host_lock); |
1340 | mempool_free( ndlp, phba->nlp_mem_pool); | 1361 | mempool_free( ndlp, phba->nlp_mem_pool); |
1341 | lpfc_els_free_iocb(phba, elsiocb); | 1362 | lpfc_els_free_iocb(phba, elsiocb); |
1342 | return (1); | 1363 | return 1; |
1343 | } | 1364 | } |
1344 | spin_unlock_irq(phba->host->host_lock); | 1365 | spin_unlock_irq(phba->host->host_lock); |
1345 | mempool_free( ndlp, phba->nlp_mem_pool); | 1366 | mempool_free( ndlp, phba->nlp_mem_pool); |
1346 | return (0); | 1367 | return 0; |
1347 | } | 1368 | } |
1348 | 1369 | ||
1349 | static int | 1370 | static int |
@@ -1363,15 +1384,16 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1363 | psli = &phba->sli; | 1384 | psli = &phba->sli; |
1364 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 1385 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1365 | cmdsize = (sizeof (uint32_t) + sizeof (FARP)); | 1386 | cmdsize = (sizeof (uint32_t) + sizeof (FARP)); |
1366 | if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) == 0) { | 1387 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
1367 | return (1); | 1388 | if (!ndlp) |
1368 | } | 1389 | return 1; |
1369 | lpfc_nlp_init(phba, ndlp, nportid); | 1390 | lpfc_nlp_init(phba, ndlp, nportid); |
1370 | 1391 | ||
1371 | if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, | 1392 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, |
1372 | ndlp, ELS_CMD_RNID)) == 0) { | 1393 | ndlp->nlp_DID, ELS_CMD_RNID); |
1394 | if (!elsiocb) { | ||
1373 | mempool_free( ndlp, phba->nlp_mem_pool); | 1395 | mempool_free( ndlp, phba->nlp_mem_pool); |
1374 | return (1); | 1396 | return 1; |
1375 | } | 1397 | } |
1376 | 1398 | ||
1377 | icmd = &elsiocb->iocb; | 1399 | icmd = &elsiocb->iocb; |
@@ -1405,11 +1427,51 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1405 | spin_unlock_irq(phba->host->host_lock); | 1427 | spin_unlock_irq(phba->host->host_lock); |
1406 | mempool_free( ndlp, phba->nlp_mem_pool); | 1428 | mempool_free( ndlp, phba->nlp_mem_pool); |
1407 | lpfc_els_free_iocb(phba, elsiocb); | 1429 | lpfc_els_free_iocb(phba, elsiocb); |
1408 | return (1); | 1430 | return 1; |
1409 | } | 1431 | } |
1410 | spin_unlock_irq(phba->host->host_lock); | 1432 | spin_unlock_irq(phba->host->host_lock); |
1411 | mempool_free( ndlp, phba->nlp_mem_pool); | 1433 | mempool_free( ndlp, phba->nlp_mem_pool); |
1412 | return (0); | 1434 | return 0; |
1435 | } | ||
1436 | |||
1437 | void | ||
1438 | lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp) | ||
1439 | { | ||
1440 | nlp->nlp_flag &= ~NLP_DELAY_TMO; | ||
1441 | del_timer_sync(&nlp->nlp_delayfunc); | ||
1442 | nlp->nlp_last_elscmd = 0; | ||
1443 | |||
1444 | if (!list_empty(&nlp->els_retry_evt.evt_listp)) | ||
1445 | list_del_init(&nlp->els_retry_evt.evt_listp); | ||
1446 | |||
1447 | if (nlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
1448 | nlp->nlp_flag &= ~NLP_NPR_2B_DISC; | ||
1449 | if (phba->num_disc_nodes) { | ||
1450 | /* Check to see if there are more | ||
1451 | * PLOGIs to be sent | ||
1452 | */ | ||
1453 | lpfc_more_plogi(phba); | ||
1454 | } | ||
1455 | |||
1456 | if (phba->num_disc_nodes == 0) { | ||
1457 | phba->fc_flag &= ~FC_NDISC_ACTIVE; | ||
1458 | lpfc_can_disctmo(phba); | ||
1459 | if (phba->fc_flag & FC_RSCN_MODE) { | ||
1460 | /* Check to see if more RSCNs | ||
1461 | * came in while we were | ||
1462 | * processing this one. | ||
1463 | */ | ||
1464 | if((phba->fc_rscn_id_cnt==0) && | ||
1465 | (!(phba->fc_flag & FC_RSCN_DISCOVERY))) { | ||
1466 | phba->fc_flag &= ~FC_RSCN_MODE; | ||
1467 | } | ||
1468 | else { | ||
1469 | lpfc_els_handle_rscn(phba); | ||
1470 | } | ||
1471 | } | ||
1472 | } | ||
1473 | } | ||
1474 | return; | ||
1413 | } | 1475 | } |
1414 | 1476 | ||
1415 | void | 1477 | void |
@@ -1450,8 +1512,9 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | |||
1450 | 1512 | ||
1451 | phba = ndlp->nlp_phba; | 1513 | phba = ndlp->nlp_phba; |
1452 | spin_lock_irq(phba->host->host_lock); | 1514 | spin_lock_irq(phba->host->host_lock); |
1453 | did = (uint32_t) (ndlp->nlp_DID); | 1515 | did = ndlp->nlp_DID; |
1454 | cmd = (uint32_t) (ndlp->nlp_last_elscmd); | 1516 | cmd = ndlp->nlp_last_elscmd; |
1517 | ndlp->nlp_last_elscmd = 0; | ||
1455 | 1518 | ||
1456 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1519 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1457 | spin_unlock_irq(phba->host->host_lock); | 1520 | spin_unlock_irq(phba->host->host_lock); |
@@ -1460,6 +1523,12 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | |||
1460 | 1523 | ||
1461 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 1524 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; |
1462 | spin_unlock_irq(phba->host->host_lock); | 1525 | spin_unlock_irq(phba->host->host_lock); |
1526 | /* | ||
1527 | * If a discovery event readded nlp_delayfunc after timer | ||
1528 | * firing and before processing the timer, cancel the | ||
1529 | * nlp_delayfunc. | ||
1530 | */ | ||
1531 | del_timer_sync(&ndlp->nlp_delayfunc); | ||
1463 | retry = ndlp->nlp_retry; | 1532 | retry = ndlp->nlp_retry; |
1464 | 1533 | ||
1465 | switch (cmd) { | 1534 | switch (cmd) { |
@@ -1467,24 +1536,32 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | |||
1467 | lpfc_issue_els_flogi(phba, ndlp, retry); | 1536 | lpfc_issue_els_flogi(phba, ndlp, retry); |
1468 | break; | 1537 | break; |
1469 | case ELS_CMD_PLOGI: | 1538 | case ELS_CMD_PLOGI: |
1470 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1539 | if(!lpfc_issue_els_plogi(phba, ndlp->nlp_DID, retry)) { |
1471 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1540 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1472 | lpfc_issue_els_plogi(phba, ndlp, retry); | 1541 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1542 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | ||
1543 | } | ||
1473 | break; | 1544 | break; |
1474 | case ELS_CMD_ADISC: | 1545 | case ELS_CMD_ADISC: |
1475 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1546 | if (!lpfc_issue_els_adisc(phba, ndlp, retry)) { |
1476 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | 1547 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1477 | lpfc_issue_els_adisc(phba, ndlp, retry); | 1548 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
1549 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | ||
1550 | } | ||
1478 | break; | 1551 | break; |
1479 | case ELS_CMD_PRLI: | 1552 | case ELS_CMD_PRLI: |
1480 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; | 1553 | if (!lpfc_issue_els_prli(phba, ndlp, retry)) { |
1481 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); | 1554 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1482 | lpfc_issue_els_prli(phba, ndlp, retry); | 1555 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; |
1556 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); | ||
1557 | } | ||
1483 | break; | 1558 | break; |
1484 | case ELS_CMD_LOGO: | 1559 | case ELS_CMD_LOGO: |
1485 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1560 | if (!lpfc_issue_els_logo(phba, ndlp, retry)) { |
1486 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1561 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1487 | lpfc_issue_els_logo(phba, ndlp, retry); | 1562 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1563 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | ||
1564 | } | ||
1488 | break; | 1565 | break; |
1489 | } | 1566 | } |
1490 | return; | 1567 | return; |
@@ -1502,6 +1579,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1502 | int retry, maxretry; | 1579 | int retry, maxretry; |
1503 | int delay; | 1580 | int delay; |
1504 | uint32_t cmd; | 1581 | uint32_t cmd; |
1582 | uint32_t did; | ||
1505 | 1583 | ||
1506 | retry = 0; | 1584 | retry = 0; |
1507 | delay = 0; | 1585 | delay = 0; |
@@ -1510,6 +1588,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1510 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 1588 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
1511 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 1589 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
1512 | cmd = 0; | 1590 | cmd = 0; |
1591 | |||
1513 | /* Note: context2 may be 0 for internal driver abort | 1592 | /* Note: context2 may be 0 for internal driver abort |
1514 | * of delays ELS command. | 1593 | * of delays ELS command. |
1515 | */ | 1594 | */ |
@@ -1519,6 +1598,16 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1519 | cmd = *elscmd++; | 1598 | cmd = *elscmd++; |
1520 | } | 1599 | } |
1521 | 1600 | ||
1601 | if(ndlp) | ||
1602 | did = ndlp->nlp_DID; | ||
1603 | else { | ||
1604 | /* We should only hit this case for retrying PLOGI */ | ||
1605 | did = irsp->un.elsreq64.remoteID; | ||
1606 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); | ||
1607 | if (!ndlp && (cmd != ELS_CMD_PLOGI)) | ||
1608 | return 1; | ||
1609 | } | ||
1610 | |||
1522 | switch (irsp->ulpStatus) { | 1611 | switch (irsp->ulpStatus) { |
1523 | case IOSTAT_FCP_RSP_ERROR: | 1612 | case IOSTAT_FCP_RSP_ERROR: |
1524 | case IOSTAT_REMOTE_STOP: | 1613 | case IOSTAT_REMOTE_STOP: |
@@ -1537,11 +1626,6 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1537 | 1626 | ||
1538 | case IOERR_SEQUENCE_TIMEOUT: | 1627 | case IOERR_SEQUENCE_TIMEOUT: |
1539 | retry = 1; | 1628 | retry = 1; |
1540 | if ((cmd == ELS_CMD_FLOGI) | ||
1541 | && (phba->fc_topology != TOPOLOGY_LOOP)) { | ||
1542 | delay = 1; | ||
1543 | maxretry = 48; | ||
1544 | } | ||
1545 | break; | 1629 | break; |
1546 | 1630 | ||
1547 | case IOERR_NO_RESOURCES: | 1631 | case IOERR_NO_RESOURCES: |
@@ -1612,9 +1696,8 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1612 | break; | 1696 | break; |
1613 | } | 1697 | } |
1614 | 1698 | ||
1615 | if (ndlp->nlp_DID == FDMI_DID) { | 1699 | if (did == FDMI_DID) |
1616 | retry = 1; | 1700 | retry = 1; |
1617 | } | ||
1618 | 1701 | ||
1619 | if ((++cmdiocb->retry) >= maxretry) { | 1702 | if ((++cmdiocb->retry) >= maxretry) { |
1620 | phba->fc_stat.elsRetryExceeded++; | 1703 | phba->fc_stat.elsRetryExceeded++; |
@@ -1628,7 +1711,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1628 | "%d:0107 Retry ELS command x%x to remote " | 1711 | "%d:0107 Retry ELS command x%x to remote " |
1629 | "NPORT x%x Data: x%x x%x\n", | 1712 | "NPORT x%x Data: x%x x%x\n", |
1630 | phba->brd_no, | 1713 | phba->brd_no, |
1631 | cmd, ndlp->nlp_DID, cmdiocb->retry, delay); | 1714 | cmd, did, cmdiocb->retry, delay); |
1632 | 1715 | ||
1633 | if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) { | 1716 | if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) { |
1634 | /* If discovery / RSCN timer is running, reset it */ | 1717 | /* If discovery / RSCN timer is running, reset it */ |
@@ -1639,54 +1722,61 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1639 | } | 1722 | } |
1640 | 1723 | ||
1641 | phba->fc_stat.elsXmitRetry++; | 1724 | phba->fc_stat.elsXmitRetry++; |
1642 | if (delay) { | 1725 | if (ndlp && delay) { |
1643 | phba->fc_stat.elsDelayRetry++; | 1726 | phba->fc_stat.elsDelayRetry++; |
1644 | ndlp->nlp_retry = cmdiocb->retry; | 1727 | ndlp->nlp_retry = cmdiocb->retry; |
1645 | 1728 | ||
1646 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 1729 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
1647 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1730 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1648 | 1731 | ||
1732 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1649 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1733 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1650 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1734 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1651 | ndlp->nlp_last_elscmd = cmd; | 1735 | ndlp->nlp_last_elscmd = cmd; |
1652 | 1736 | ||
1653 | return (1); | 1737 | return 1; |
1654 | } | 1738 | } |
1655 | switch (cmd) { | 1739 | switch (cmd) { |
1656 | case ELS_CMD_FLOGI: | 1740 | case ELS_CMD_FLOGI: |
1657 | lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry); | 1741 | lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry); |
1658 | return (1); | 1742 | return 1; |
1659 | case ELS_CMD_PLOGI: | 1743 | case ELS_CMD_PLOGI: |
1660 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1744 | if (ndlp) { |
1661 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1745 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1662 | lpfc_issue_els_plogi(phba, ndlp, cmdiocb->retry); | 1746 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1663 | return (1); | 1747 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1748 | } | ||
1749 | lpfc_issue_els_plogi(phba, did, cmdiocb->retry); | ||
1750 | return 1; | ||
1664 | case ELS_CMD_ADISC: | 1751 | case ELS_CMD_ADISC: |
1752 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1665 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1753 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
1666 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | 1754 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); |
1667 | lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry); | 1755 | lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry); |
1668 | return (1); | 1756 | return 1; |
1669 | case ELS_CMD_PRLI: | 1757 | case ELS_CMD_PRLI: |
1758 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1670 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; | 1759 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; |
1671 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); | 1760 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); |
1672 | lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry); | 1761 | lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry); |
1673 | return (1); | 1762 | return 1; |
1674 | case ELS_CMD_LOGO: | 1763 | case ELS_CMD_LOGO: |
1764 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1675 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1765 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1676 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1766 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1677 | lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry); | 1767 | lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry); |
1678 | return (1); | 1768 | return 1; |
1679 | } | 1769 | } |
1680 | } | 1770 | } |
1681 | 1771 | ||
1682 | /* No retry ELS command <elsCmd> to remote NPORT <did> */ | 1772 | /* No retry ELS command <elsCmd> to remote NPORT <did> */ |
1683 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1773 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
1684 | "%d:0108 No retry ELS command x%x to remote NPORT x%x " | 1774 | "%d:0108 No retry ELS command x%x to remote NPORT x%x " |
1685 | "Data: x%x x%x\n", | 1775 | "Data: x%x\n", |
1686 | phba->brd_no, | 1776 | phba->brd_no, |
1687 | cmd, ndlp->nlp_DID, cmdiocb->retry, ndlp->nlp_flag); | 1777 | cmd, did, cmdiocb->retry); |
1688 | 1778 | ||
1689 | return (0); | 1779 | return 0; |
1690 | } | 1780 | } |
1691 | 1781 | ||
1692 | int | 1782 | int |
@@ -1735,10 +1825,6 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1735 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, | 1825 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, |
1736 | ndlp->nlp_state, ndlp->nlp_rpi); | 1826 | ndlp->nlp_state, ndlp->nlp_rpi); |
1737 | 1827 | ||
1738 | spin_lock_irq(phba->host->host_lock); | ||
1739 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; | ||
1740 | spin_unlock_irq(phba->host->host_lock); | ||
1741 | |||
1742 | switch (ndlp->nlp_state) { | 1828 | switch (ndlp->nlp_state) { |
1743 | case NLP_STE_UNUSED_NODE: /* node is just allocated */ | 1829 | case NLP_STE_UNUSED_NODE: /* node is just allocated */ |
1744 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1830 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
@@ -1776,11 +1862,12 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1776 | /* ELS response tag <ulpIoTag> completes */ | 1862 | /* ELS response tag <ulpIoTag> completes */ |
1777 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1863 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
1778 | "%d:0110 ELS response tag x%x completes " | 1864 | "%d:0110 ELS response tag x%x completes " |
1779 | "Data: x%x x%x x%x x%x x%x x%x\n", | 1865 | "Data: x%x x%x x%x x%x x%x x%x x%x\n", |
1780 | phba->brd_no, | 1866 | phba->brd_no, |
1781 | cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus, | 1867 | cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus, |
1782 | rspiocb->iocb.un.ulpWord[4], ndlp->nlp_DID, | 1868 | rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout, |
1783 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); | 1869 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, |
1870 | ndlp->nlp_rpi); | ||
1784 | 1871 | ||
1785 | if (mbox) { | 1872 | if (mbox) { |
1786 | if ((rspiocb->iocb.ulpStatus == 0) | 1873 | if ((rspiocb->iocb.ulpStatus == 0) |
@@ -1791,6 +1878,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1791 | lpfc_unreg_rpi(phba, ndlp); | 1878 | lpfc_unreg_rpi(phba, ndlp); |
1792 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | 1879 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
1793 | mbox->context2 = ndlp; | 1880 | mbox->context2 = ndlp; |
1881 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1794 | ndlp->nlp_state = NLP_STE_REG_LOGIN_ISSUE; | 1882 | ndlp->nlp_state = NLP_STE_REG_LOGIN_ISSUE; |
1795 | lpfc_nlp_list(phba, ndlp, NLP_REGLOGIN_LIST); | 1883 | lpfc_nlp_list(phba, ndlp, NLP_REGLOGIN_LIST); |
1796 | if (lpfc_sli_issue_mbox(phba, mbox, | 1884 | if (lpfc_sli_issue_mbox(phba, mbox, |
@@ -1805,6 +1893,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1805 | mempool_free( mbox, phba->mbox_mem_pool); | 1893 | mempool_free( mbox, phba->mbox_mem_pool); |
1806 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | 1894 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { |
1807 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1895 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
1896 | ndlp = NULL; | ||
1808 | } | 1897 | } |
1809 | } | 1898 | } |
1810 | } | 1899 | } |
@@ -1839,10 +1928,11 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1839 | switch (flag) { | 1928 | switch (flag) { |
1840 | case ELS_CMD_ACC: | 1929 | case ELS_CMD_ACC: |
1841 | cmdsize = sizeof (uint32_t); | 1930 | cmdsize = sizeof (uint32_t); |
1842 | if ((elsiocb = | 1931 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
1843 | lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 1932 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
1844 | ndlp, ELS_CMD_ACC)) == 0) { | 1933 | if (!elsiocb) { |
1845 | return (1); | 1934 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; |
1935 | return 1; | ||
1846 | } | 1936 | } |
1847 | icmd = &elsiocb->iocb; | 1937 | icmd = &elsiocb->iocb; |
1848 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ | 1938 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ |
@@ -1852,11 +1942,11 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1852 | break; | 1942 | break; |
1853 | case ELS_CMD_PLOGI: | 1943 | case ELS_CMD_PLOGI: |
1854 | cmdsize = (sizeof (struct serv_parm) + sizeof (uint32_t)); | 1944 | cmdsize = (sizeof (struct serv_parm) + sizeof (uint32_t)); |
1855 | if ((elsiocb = | 1945 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
1856 | lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 1946 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
1857 | ndlp, ELS_CMD_ACC)) == 0) { | 1947 | if (!elsiocb) |
1858 | return (1); | 1948 | return 1; |
1859 | } | 1949 | |
1860 | icmd = &elsiocb->iocb; | 1950 | icmd = &elsiocb->iocb; |
1861 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ | 1951 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ |
1862 | pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 1952 | pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
@@ -1869,7 +1959,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1869 | memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); | 1959 | memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); |
1870 | break; | 1960 | break; |
1871 | default: | 1961 | default: |
1872 | return (1); | 1962 | return 1; |
1873 | } | 1963 | } |
1874 | 1964 | ||
1875 | if (newnode) | 1965 | if (newnode) |
@@ -1885,6 +1975,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1885 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); | 1975 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); |
1886 | 1976 | ||
1887 | if (ndlp->nlp_flag & NLP_LOGO_ACC) { | 1977 | if (ndlp->nlp_flag & NLP_LOGO_ACC) { |
1978 | spin_lock_irq(phba->host->host_lock); | ||
1979 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; | ||
1980 | spin_unlock_irq(phba->host->host_lock); | ||
1888 | elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc; | 1981 | elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc; |
1889 | } else { | 1982 | } else { |
1890 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 1983 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; |
@@ -1896,9 +1989,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1896 | spin_unlock_irq(phba->host->host_lock); | 1989 | spin_unlock_irq(phba->host->host_lock); |
1897 | if (rc == IOCB_ERROR) { | 1990 | if (rc == IOCB_ERROR) { |
1898 | lpfc_els_free_iocb(phba, elsiocb); | 1991 | lpfc_els_free_iocb(phba, elsiocb); |
1899 | return (1); | 1992 | return 1; |
1900 | } | 1993 | } |
1901 | return (0); | 1994 | return 0; |
1902 | } | 1995 | } |
1903 | 1996 | ||
1904 | int | 1997 | int |
@@ -1918,10 +2011,10 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, | |||
1918 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 2011 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1919 | 2012 | ||
1920 | cmdsize = 2 * sizeof (uint32_t); | 2013 | cmdsize = 2 * sizeof (uint32_t); |
1921 | if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 2014 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
1922 | ndlp, ELS_CMD_LS_RJT)) == 0) { | 2015 | ndlp, ndlp->nlp_DID, ELS_CMD_LS_RJT); |
1923 | return (1); | 2016 | if (!elsiocb) |
1924 | } | 2017 | return 1; |
1925 | 2018 | ||
1926 | icmd = &elsiocb->iocb; | 2019 | icmd = &elsiocb->iocb; |
1927 | oldcmd = &oldiocb->iocb; | 2020 | oldcmd = &oldiocb->iocb; |
@@ -1948,9 +2041,9 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, | |||
1948 | spin_unlock_irq(phba->host->host_lock); | 2041 | spin_unlock_irq(phba->host->host_lock); |
1949 | if (rc == IOCB_ERROR) { | 2042 | if (rc == IOCB_ERROR) { |
1950 | lpfc_els_free_iocb(phba, elsiocb); | 2043 | lpfc_els_free_iocb(phba, elsiocb); |
1951 | return (1); | 2044 | return 1; |
1952 | } | 2045 | } |
1953 | return (0); | 2046 | return 0; |
1954 | } | 2047 | } |
1955 | 2048 | ||
1956 | int | 2049 | int |
@@ -1971,10 +2064,10 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, | |||
1971 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 2064 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1972 | 2065 | ||
1973 | cmdsize = sizeof (uint32_t) + sizeof (ADISC); | 2066 | cmdsize = sizeof (uint32_t) + sizeof (ADISC); |
1974 | if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 2067 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
1975 | ndlp, ELS_CMD_ACC)) == 0) { | 2068 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
1976 | return (1); | 2069 | if (!elsiocb) |
1977 | } | 2070 | return 1; |
1978 | 2071 | ||
1979 | /* Xmit ADISC ACC response tag <ulpIoTag> */ | 2072 | /* Xmit ADISC ACC response tag <ulpIoTag> */ |
1980 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2073 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -2006,9 +2099,9 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, | |||
2006 | spin_unlock_irq(phba->host->host_lock); | 2099 | spin_unlock_irq(phba->host->host_lock); |
2007 | if (rc == IOCB_ERROR) { | 2100 | if (rc == IOCB_ERROR) { |
2008 | lpfc_els_free_iocb(phba, elsiocb); | 2101 | lpfc_els_free_iocb(phba, elsiocb); |
2009 | return (1); | 2102 | return 1; |
2010 | } | 2103 | } |
2011 | return (0); | 2104 | return 0; |
2012 | } | 2105 | } |
2013 | 2106 | ||
2014 | int | 2107 | int |
@@ -2030,13 +2123,10 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba, | |||
2030 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 2123 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
2031 | 2124 | ||
2032 | cmdsize = sizeof (uint32_t) + sizeof (PRLI); | 2125 | cmdsize = sizeof (uint32_t) + sizeof (PRLI); |
2033 | if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 2126 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, ndlp, |
2034 | ndlp, | 2127 | ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK))); |
2035 | (ELS_CMD_ACC | | 2128 | if (!elsiocb) |
2036 | (ELS_CMD_PRLI & ~ELS_RSP_MASK)))) == | 2129 | return 1; |
2037 | 0) { | ||
2038 | return (1); | ||
2039 | } | ||
2040 | 2130 | ||
2041 | /* Xmit PRLI ACC response tag <ulpIoTag> */ | 2131 | /* Xmit PRLI ACC response tag <ulpIoTag> */ |
2042 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2132 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -2086,9 +2176,9 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba, | |||
2086 | spin_unlock_irq(phba->host->host_lock); | 2176 | spin_unlock_irq(phba->host->host_lock); |
2087 | if (rc == IOCB_ERROR) { | 2177 | if (rc == IOCB_ERROR) { |
2088 | lpfc_els_free_iocb(phba, elsiocb); | 2178 | lpfc_els_free_iocb(phba, elsiocb); |
2089 | return (1); | 2179 | return 1; |
2090 | } | 2180 | } |
2091 | return (0); | 2181 | return 0; |
2092 | } | 2182 | } |
2093 | 2183 | ||
2094 | static int | 2184 | static int |
@@ -2114,10 +2204,10 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, | |||
2114 | if (format) | 2204 | if (format) |
2115 | cmdsize += sizeof (RNID_TOP_DISC); | 2205 | cmdsize += sizeof (RNID_TOP_DISC); |
2116 | 2206 | ||
2117 | if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 2207 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
2118 | ndlp, ELS_CMD_ACC)) == 0) { | 2208 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); |
2119 | return (1); | 2209 | if (!elsiocb) |
2120 | } | 2210 | return 1; |
2121 | 2211 | ||
2122 | /* Xmit RNID ACC response tag <ulpIoTag> */ | 2212 | /* Xmit RNID ACC response tag <ulpIoTag> */ |
2123 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2213 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -2169,9 +2259,9 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, | |||
2169 | spin_unlock_irq(phba->host->host_lock); | 2259 | spin_unlock_irq(phba->host->host_lock); |
2170 | if (rc == IOCB_ERROR) { | 2260 | if (rc == IOCB_ERROR) { |
2171 | lpfc_els_free_iocb(phba, elsiocb); | 2261 | lpfc_els_free_iocb(phba, elsiocb); |
2172 | return (1); | 2262 | return 1; |
2173 | } | 2263 | } |
2174 | return (0); | 2264 | return 0; |
2175 | } | 2265 | } |
2176 | 2266 | ||
2177 | int | 2267 | int |
@@ -2187,6 +2277,7 @@ lpfc_els_disc_adisc(struct lpfc_hba * phba) | |||
2187 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 2277 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { |
2188 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 2278 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
2189 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 2279 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
2280 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
2190 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 2281 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
2191 | lpfc_nlp_list(phba, ndlp, | 2282 | lpfc_nlp_list(phba, ndlp, |
2192 | NLP_ADISC_LIST); | 2283 | NLP_ADISC_LIST); |
@@ -2208,7 +2299,7 @@ lpfc_els_disc_adisc(struct lpfc_hba * phba) | |||
2208 | phba->fc_flag &= ~FC_NLP_MORE; | 2299 | phba->fc_flag &= ~FC_NLP_MORE; |
2209 | spin_unlock_irq(phba->host->host_lock); | 2300 | spin_unlock_irq(phba->host->host_lock); |
2210 | } | 2301 | } |
2211 | return(sentadisc); | 2302 | return sentadisc; |
2212 | } | 2303 | } |
2213 | 2304 | ||
2214 | int | 2305 | int |
@@ -2224,9 +2315,10 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba) | |||
2224 | if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 2315 | if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
2225 | (!(ndlp->nlp_flag & NLP_DELAY_TMO))) { | 2316 | (!(ndlp->nlp_flag & NLP_DELAY_TMO))) { |
2226 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 2317 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { |
2318 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
2227 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 2319 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
2228 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 2320 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
2229 | lpfc_issue_els_plogi(phba, ndlp, 0); | 2321 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
2230 | sentplogi++; | 2322 | sentplogi++; |
2231 | phba->num_disc_nodes++; | 2323 | phba->num_disc_nodes++; |
2232 | if (phba->num_disc_nodes >= | 2324 | if (phba->num_disc_nodes >= |
@@ -2244,7 +2336,7 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba) | |||
2244 | phba->fc_flag &= ~FC_NLP_MORE; | 2336 | phba->fc_flag &= ~FC_NLP_MORE; |
2245 | spin_unlock_irq(phba->host->host_lock); | 2337 | spin_unlock_irq(phba->host->host_lock); |
2246 | } | 2338 | } |
2247 | return(sentplogi); | 2339 | return sentplogi; |
2248 | } | 2340 | } |
2249 | 2341 | ||
2250 | int | 2342 | int |
@@ -2264,7 +2356,7 @@ lpfc_els_flush_rscn(struct lpfc_hba * phba) | |||
2264 | phba->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY); | 2356 | phba->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY); |
2265 | spin_unlock_irq(phba->host->host_lock); | 2357 | spin_unlock_irq(phba->host->host_lock); |
2266 | lpfc_can_disctmo(phba); | 2358 | lpfc_can_disctmo(phba); |
2267 | return (0); | 2359 | return 0; |
2268 | } | 2360 | } |
2269 | 2361 | ||
2270 | int | 2362 | int |
@@ -2285,7 +2377,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) | |||
2285 | 2377 | ||
2286 | /* If we are doing a FULL RSCN rediscovery, match everything */ | 2378 | /* If we are doing a FULL RSCN rediscovery, match everything */ |
2287 | if (phba->fc_flag & FC_RSCN_DISCOVERY) { | 2379 | if (phba->fc_flag & FC_RSCN_DISCOVERY) { |
2288 | return (did); | 2380 | return did; |
2289 | } | 2381 | } |
2290 | 2382 | ||
2291 | for (i = 0; i < phba->fc_rscn_id_cnt; i++) { | 2383 | for (i = 0; i < phba->fc_rscn_id_cnt; i++) { |
@@ -2333,7 +2425,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) | |||
2333 | } | 2425 | } |
2334 | } | 2426 | } |
2335 | } | 2427 | } |
2336 | return (match); | 2428 | return match; |
2337 | } | 2429 | } |
2338 | 2430 | ||
2339 | static int | 2431 | static int |
@@ -2365,17 +2457,15 @@ lpfc_rscn_recovery_check(struct lpfc_hba * phba) | |||
2365 | 2457 | ||
2366 | lpfc_disc_state_machine(phba, ndlp, NULL, | 2458 | lpfc_disc_state_machine(phba, ndlp, NULL, |
2367 | NLP_EVT_DEVICE_RECOVERY); | 2459 | NLP_EVT_DEVICE_RECOVERY); |
2368 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 2460 | |
2369 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 2461 | /* Make sure NLP_DELAY_TMO is NOT running |
2370 | del_timer_sync(&ndlp->nlp_delayfunc); | 2462 | * after a device recovery event. |
2371 | if (!list_empty(&ndlp-> | 2463 | */ |
2372 | els_retry_evt.evt_listp)) | 2464 | if (ndlp->nlp_flag & NLP_DELAY_TMO) |
2373 | list_del_init(&ndlp-> | 2465 | lpfc_cancel_retry_delay_tmo(phba, ndlp); |
2374 | els_retry_evt.evt_listp); | ||
2375 | } | ||
2376 | } | 2466 | } |
2377 | } | 2467 | } |
2378 | return (0); | 2468 | return 0; |
2379 | } | 2469 | } |
2380 | 2470 | ||
2381 | static int | 2471 | static int |
@@ -2411,7 +2501,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, | |||
2411 | if (phba->hba_state < LPFC_NS_QRY) { | 2501 | if (phba->hba_state < LPFC_NS_QRY) { |
2412 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, | 2502 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, |
2413 | newnode); | 2503 | newnode); |
2414 | return (0); | 2504 | return 0; |
2415 | } | 2505 | } |
2416 | 2506 | ||
2417 | /* If we are already processing an RSCN, save the received | 2507 | /* If we are already processing an RSCN, save the received |
@@ -2453,7 +2543,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, | |||
2453 | 2543 | ||
2454 | /* send RECOVERY event for ALL nodes that match RSCN payload */ | 2544 | /* send RECOVERY event for ALL nodes that match RSCN payload */ |
2455 | lpfc_rscn_recovery_check(phba); | 2545 | lpfc_rscn_recovery_check(phba); |
2456 | return (0); | 2546 | return 0; |
2457 | } | 2547 | } |
2458 | 2548 | ||
2459 | phba->fc_flag |= FC_RSCN_MODE; | 2549 | phba->fc_flag |= FC_RSCN_MODE; |
@@ -2472,7 +2562,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, | |||
2472 | /* send RECOVERY event for ALL nodes that match RSCN payload */ | 2562 | /* send RECOVERY event for ALL nodes that match RSCN payload */ |
2473 | lpfc_rscn_recovery_check(phba); | 2563 | lpfc_rscn_recovery_check(phba); |
2474 | 2564 | ||
2475 | return (lpfc_els_handle_rscn(phba)); | 2565 | return lpfc_els_handle_rscn(phba); |
2476 | } | 2566 | } |
2477 | 2567 | ||
2478 | int | 2568 | int |
@@ -2494,40 +2584,41 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) | |||
2494 | 2584 | ||
2495 | /* To process RSCN, first compare RSCN data with NameServer */ | 2585 | /* To process RSCN, first compare RSCN data with NameServer */ |
2496 | phba->fc_ns_retry = 0; | 2586 | phba->fc_ns_retry = 0; |
2497 | if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, | 2587 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, NameServer_DID); |
2498 | NameServer_DID))) { | 2588 | if (ndlp) { |
2499 | /* Good ndlp, issue CT Request to NameServer */ | 2589 | /* Good ndlp, issue CT Request to NameServer */ |
2500 | if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { | 2590 | if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { |
2501 | /* Wait for NameServer query cmpl before we can | 2591 | /* Wait for NameServer query cmpl before we can |
2502 | continue */ | 2592 | continue */ |
2503 | return (1); | 2593 | return 1; |
2504 | } | 2594 | } |
2505 | } else { | 2595 | } else { |
2506 | /* If login to NameServer does not exist, issue one */ | 2596 | /* If login to NameServer does not exist, issue one */ |
2507 | /* Good status, issue PLOGI to NameServer */ | 2597 | /* Good status, issue PLOGI to NameServer */ |
2508 | if ((ndlp = | 2598 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); |
2509 | lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID))) { | 2599 | if (ndlp) { |
2510 | /* Wait for NameServer login cmpl before we can | 2600 | /* Wait for NameServer login cmpl before we can |
2511 | continue */ | 2601 | continue */ |
2512 | return (1); | 2602 | return 1; |
2513 | } | 2603 | } |
2514 | if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) | 2604 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
2515 | == 0) { | 2605 | if (!ndlp) { |
2516 | lpfc_els_flush_rscn(phba); | 2606 | lpfc_els_flush_rscn(phba); |
2517 | return (0); | 2607 | return 0; |
2518 | } else { | 2608 | } else { |
2519 | lpfc_nlp_init(phba, ndlp, NameServer_DID); | 2609 | lpfc_nlp_init(phba, ndlp, NameServer_DID); |
2520 | ndlp->nlp_type |= NLP_FABRIC; | 2610 | ndlp->nlp_type |= NLP_FABRIC; |
2611 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
2521 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 2612 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
2522 | lpfc_issue_els_plogi(phba, ndlp, 0); | 2613 | lpfc_issue_els_plogi(phba, NameServer_DID, 0); |
2523 | /* Wait for NameServer login cmpl before we can | 2614 | /* Wait for NameServer login cmpl before we can |
2524 | continue */ | 2615 | continue */ |
2525 | return (1); | 2616 | return 1; |
2526 | } | 2617 | } |
2527 | } | 2618 | } |
2528 | 2619 | ||
2529 | lpfc_els_flush_rscn(phba); | 2620 | lpfc_els_flush_rscn(phba); |
2530 | return (0); | 2621 | return 0; |
2531 | } | 2622 | } |
2532 | 2623 | ||
2533 | static int | 2624 | static int |
@@ -2561,7 +2652,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, | |||
2561 | "%d:0113 An FLOGI ELS command x%x was received " | 2652 | "%d:0113 An FLOGI ELS command x%x was received " |
2562 | "from DID x%x in Loop Mode\n", | 2653 | "from DID x%x in Loop Mode\n", |
2563 | phba->brd_no, cmd, did); | 2654 | phba->brd_no, cmd, did); |
2564 | return (1); | 2655 | return 1; |
2565 | } | 2656 | } |
2566 | 2657 | ||
2567 | did = Fabric_DID; | 2658 | did = Fabric_DID; |
@@ -2577,7 +2668,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, | |||
2577 | if (!rc) { | 2668 | if (!rc) { |
2578 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, | 2669 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, |
2579 | GFP_KERNEL)) == 0) { | 2670 | GFP_KERNEL)) == 0) { |
2580 | return (1); | 2671 | return 1; |
2581 | } | 2672 | } |
2582 | lpfc_linkdown(phba); | 2673 | lpfc_linkdown(phba); |
2583 | lpfc_init_link(phba, mbox, | 2674 | lpfc_init_link(phba, mbox, |
@@ -2590,9 +2681,8 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, | |||
2590 | if (rc == MBX_NOT_FINISHED) { | 2681 | if (rc == MBX_NOT_FINISHED) { |
2591 | mempool_free( mbox, phba->mbox_mem_pool); | 2682 | mempool_free( mbox, phba->mbox_mem_pool); |
2592 | } | 2683 | } |
2593 | return (1); | 2684 | return 1; |
2594 | } | 2685 | } else if (rc > 0) { /* greater than */ |
2595 | else if (rc > 0) { /* greater than */ | ||
2596 | spin_lock_irq(phba->host->host_lock); | 2686 | spin_lock_irq(phba->host->host_lock); |
2597 | phba->fc_flag |= FC_PT2PT_PLOGI; | 2687 | phba->fc_flag |= FC_PT2PT_PLOGI; |
2598 | spin_unlock_irq(phba->host->host_lock); | 2688 | spin_unlock_irq(phba->host->host_lock); |
@@ -2606,13 +2696,13 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, | |||
2606 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; | 2696 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; |
2607 | stat.un.b.vendorUnique = 0; | 2697 | stat.un.b.vendorUnique = 0; |
2608 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 2698 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
2609 | return (1); | 2699 | return 1; |
2610 | } | 2700 | } |
2611 | 2701 | ||
2612 | /* Send back ACC */ | 2702 | /* Send back ACC */ |
2613 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode); | 2703 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode); |
2614 | 2704 | ||
2615 | return (0); | 2705 | return 0; |
2616 | } | 2706 | } |
2617 | 2707 | ||
2618 | static int | 2708 | static int |
@@ -2650,45 +2740,246 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba, | |||
2650 | stat.un.b.vendorUnique = 0; | 2740 | stat.un.b.vendorUnique = 0; |
2651 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 2741 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
2652 | } | 2742 | } |
2653 | return (0); | 2743 | return 0; |
2654 | } | 2744 | } |
2655 | 2745 | ||
2656 | static int | 2746 | static int |
2657 | lpfc_els_rcv_rrq(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2747 | lpfc_els_rcv_lirr(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, |
2748 | struct lpfc_nodelist * ndlp) | ||
2749 | { | ||
2750 | struct ls_rjt stat; | ||
2751 | |||
2752 | /* For now, unconditionally reject this command */ | ||
2753 | stat.un.b.lsRjtRsvd0 = 0; | ||
2754 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | ||
2755 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | ||
2756 | stat.un.b.vendorUnique = 0; | ||
2757 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | ||
2758 | return 0; | ||
2759 | } | ||
2760 | |||
2761 | static void | ||
2762 | lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | ||
2763 | { | ||
2764 | struct lpfc_sli *psli; | ||
2765 | struct lpfc_sli_ring *pring; | ||
2766 | MAILBOX_t *mb; | ||
2767 | IOCB_t *icmd; | ||
2768 | RPS_RSP *rps_rsp; | ||
2769 | uint8_t *pcmd; | ||
2770 | struct lpfc_iocbq *elsiocb; | ||
2771 | struct lpfc_nodelist *ndlp; | ||
2772 | uint16_t xri, status; | ||
2773 | uint32_t cmdsize; | ||
2774 | |||
2775 | psli = &phba->sli; | ||
2776 | pring = &psli->ring[LPFC_ELS_RING]; | ||
2777 | mb = &pmb->mb; | ||
2778 | |||
2779 | ndlp = (struct lpfc_nodelist *) pmb->context2; | ||
2780 | xri = (uint16_t) ((unsigned long)(pmb->context1)); | ||
2781 | pmb->context1 = 0; | ||
2782 | pmb->context2 = 0; | ||
2783 | |||
2784 | if (mb->mbxStatus) { | ||
2785 | mempool_free( pmb, phba->mbox_mem_pool); | ||
2786 | return; | ||
2787 | } | ||
2788 | |||
2789 | cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); | ||
2790 | mempool_free( pmb, phba->mbox_mem_pool); | ||
2791 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, ndlp, | ||
2792 | ndlp->nlp_DID, ELS_CMD_ACC); | ||
2793 | if (!elsiocb) | ||
2794 | return; | ||
2795 | |||
2796 | icmd = &elsiocb->iocb; | ||
2797 | icmd->ulpContext = xri; | ||
2798 | |||
2799 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | ||
2800 | *((uint32_t *) (pcmd)) = ELS_CMD_ACC; | ||
2801 | pcmd += sizeof (uint32_t); /* Skip past command */ | ||
2802 | rps_rsp = (RPS_RSP *)pcmd; | ||
2803 | |||
2804 | if (phba->fc_topology != TOPOLOGY_LOOP) | ||
2805 | status = 0x10; | ||
2806 | else | ||
2807 | status = 0x8; | ||
2808 | if (phba->fc_flag & FC_FABRIC) | ||
2809 | status |= 0x4; | ||
2810 | |||
2811 | rps_rsp->rsvd1 = 0; | ||
2812 | rps_rsp->portStatus = be16_to_cpu(status); | ||
2813 | rps_rsp->linkFailureCnt = be32_to_cpu(mb->un.varRdLnk.linkFailureCnt); | ||
2814 | rps_rsp->lossSyncCnt = be32_to_cpu(mb->un.varRdLnk.lossSyncCnt); | ||
2815 | rps_rsp->lossSignalCnt = be32_to_cpu(mb->un.varRdLnk.lossSignalCnt); | ||
2816 | rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt); | ||
2817 | rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord); | ||
2818 | rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt); | ||
2819 | |||
2820 | /* Xmit ELS RPS ACC response tag <ulpIoTag> */ | ||
2821 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | ||
2822 | "%d:0128 Xmit ELS RPS ACC response tag x%x " | ||
2823 | "Data: x%x x%x x%x x%x x%x\n", | ||
2824 | phba->brd_no, | ||
2825 | elsiocb->iocb.ulpIoTag, | ||
2826 | elsiocb->iocb.ulpContext, ndlp->nlp_DID, | ||
2827 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); | ||
2828 | |||
2829 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | ||
2830 | phba->fc_stat.elsXmitACC++; | ||
2831 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | ||
2832 | lpfc_els_free_iocb(phba, elsiocb); | ||
2833 | } | ||
2834 | return; | ||
2835 | } | ||
2836 | |||
2837 | static int | ||
2838 | lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | ||
2658 | struct lpfc_nodelist * ndlp) | 2839 | struct lpfc_nodelist * ndlp) |
2659 | { | 2840 | { |
2660 | struct lpfc_dmabuf *pcmd; | ||
2661 | uint32_t *lp; | 2841 | uint32_t *lp; |
2842 | uint8_t flag; | ||
2843 | LPFC_MBOXQ_t *mbox; | ||
2844 | struct lpfc_dmabuf *pcmd; | ||
2845 | RPS *rps; | ||
2846 | struct ls_rjt stat; | ||
2847 | |||
2848 | if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && | ||
2849 | (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { | ||
2850 | stat.un.b.lsRjtRsvd0 = 0; | ||
2851 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | ||
2852 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | ||
2853 | stat.un.b.vendorUnique = 0; | ||
2854 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | ||
2855 | } | ||
2856 | |||
2857 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
2858 | lp = (uint32_t *) pcmd->virt; | ||
2859 | flag = (be32_to_cpu(*lp++) & 0xf); | ||
2860 | rps = (RPS *) lp; | ||
2861 | |||
2862 | if ((flag == 0) || | ||
2863 | ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) || | ||
2864 | ((flag == 2) && (memcmp(&rps->un.portName, &phba->fc_portname, | ||
2865 | sizeof (struct lpfc_name)) == 0))) { | ||
2866 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC))) { | ||
2867 | lpfc_read_lnk_stat(phba, mbox); | ||
2868 | mbox->context1 = | ||
2869 | (void *)((unsigned long)cmdiocb->iocb.ulpContext); | ||
2870 | mbox->context2 = ndlp; | ||
2871 | mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; | ||
2872 | if (lpfc_sli_issue_mbox (phba, mbox, | ||
2873 | (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) { | ||
2874 | /* Mbox completion will send ELS Response */ | ||
2875 | return 0; | ||
2876 | } | ||
2877 | mempool_free(mbox, phba->mbox_mem_pool); | ||
2878 | } | ||
2879 | } | ||
2880 | stat.un.b.lsRjtRsvd0 = 0; | ||
2881 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | ||
2882 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | ||
2883 | stat.un.b.vendorUnique = 0; | ||
2884 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | ||
2885 | return 0; | ||
2886 | } | ||
2887 | |||
2888 | static int | ||
2889 | lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize, | ||
2890 | struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp) | ||
2891 | { | ||
2662 | IOCB_t *icmd; | 2892 | IOCB_t *icmd; |
2893 | IOCB_t *oldcmd; | ||
2894 | RPL_RSP rpl_rsp; | ||
2895 | struct lpfc_iocbq *elsiocb; | ||
2663 | struct lpfc_sli_ring *pring; | 2896 | struct lpfc_sli_ring *pring; |
2664 | struct lpfc_sli *psli; | 2897 | struct lpfc_sli *psli; |
2665 | RRQ *rrq; | 2898 | uint8_t *pcmd; |
2666 | uint32_t cmd, did; | ||
2667 | 2899 | ||
2668 | psli = &phba->sli; | 2900 | psli = &phba->sli; |
2669 | pring = &psli->ring[LPFC_FCP_RING]; | 2901 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
2670 | icmd = &cmdiocb->iocb; | 2902 | |
2671 | did = icmd->un.elsreq64.remoteID; | 2903 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
2904 | ndlp, ndlp->nlp_DID, ELS_CMD_ACC); | ||
2905 | if (!elsiocb) | ||
2906 | return 1; | ||
2907 | |||
2908 | icmd = &elsiocb->iocb; | ||
2909 | oldcmd = &oldiocb->iocb; | ||
2910 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ | ||
2911 | |||
2912 | pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | ||
2913 | *((uint32_t *) (pcmd)) = ELS_CMD_ACC; | ||
2914 | pcmd += sizeof (uint16_t); | ||
2915 | *((uint16_t *)(pcmd)) = be16_to_cpu(cmdsize); | ||
2916 | pcmd += sizeof(uint16_t); | ||
2917 | |||
2918 | /* Setup the RPL ACC payload */ | ||
2919 | rpl_rsp.listLen = be32_to_cpu(1); | ||
2920 | rpl_rsp.index = 0; | ||
2921 | rpl_rsp.port_num_blk.portNum = 0; | ||
2922 | rpl_rsp.port_num_blk.portID = be32_to_cpu(phba->fc_myDID); | ||
2923 | memcpy(&rpl_rsp.port_num_blk.portName, &phba->fc_portname, | ||
2924 | sizeof(struct lpfc_name)); | ||
2925 | |||
2926 | memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t)); | ||
2927 | |||
2928 | |||
2929 | /* Xmit ELS RPL ACC response tag <ulpIoTag> */ | ||
2930 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | ||
2931 | "%d:0128 Xmit ELS RPL ACC response tag x%x " | ||
2932 | "Data: x%x x%x x%x x%x x%x\n", | ||
2933 | phba->brd_no, | ||
2934 | elsiocb->iocb.ulpIoTag, | ||
2935 | elsiocb->iocb.ulpContext, ndlp->nlp_DID, | ||
2936 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); | ||
2937 | |||
2938 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | ||
2939 | |||
2940 | phba->fc_stat.elsXmitACC++; | ||
2941 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | ||
2942 | lpfc_els_free_iocb(phba, elsiocb); | ||
2943 | return 1; | ||
2944 | } | ||
2945 | return 0; | ||
2946 | } | ||
2947 | |||
2948 | static int | ||
2949 | lpfc_els_rcv_rpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | ||
2950 | struct lpfc_nodelist * ndlp) | ||
2951 | { | ||
2952 | struct lpfc_dmabuf *pcmd; | ||
2953 | uint32_t *lp; | ||
2954 | uint32_t maxsize; | ||
2955 | uint16_t cmdsize; | ||
2956 | RPL *rpl; | ||
2957 | struct ls_rjt stat; | ||
2958 | |||
2959 | if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && | ||
2960 | (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { | ||
2961 | stat.un.b.lsRjtRsvd0 = 0; | ||
2962 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | ||
2963 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | ||
2964 | stat.un.b.vendorUnique = 0; | ||
2965 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | ||
2966 | } | ||
2967 | |||
2672 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 2968 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
2673 | lp = (uint32_t *) pcmd->virt; | 2969 | lp = (uint32_t *) pcmd->virt; |
2970 | rpl = (RPL *) (lp + 1); | ||
2674 | 2971 | ||
2675 | cmd = *lp++; | 2972 | maxsize = be32_to_cpu(rpl->maxsize); |
2676 | rrq = (RRQ *) lp; | ||
2677 | 2973 | ||
2678 | /* RRQ received */ | 2974 | /* We support only one port */ |
2679 | /* Get oxid / rxid from payload and abort it */ | 2975 | if ((rpl->index == 0) && |
2680 | spin_lock_irq(phba->host->host_lock); | 2976 | ((maxsize == 0) || |
2681 | if ((rrq->SID == be32_to_cpu(phba->fc_myDID))) { | 2977 | ((maxsize * sizeof(uint32_t)) >= sizeof(RPL_RSP)))) { |
2682 | lpfc_sli_abort_iocb(phba, pring, 0, 0, rrq->Oxid, | 2978 | cmdsize = sizeof(uint32_t) + sizeof(RPL_RSP); |
2683 | LPFC_CTX_CTX); | ||
2684 | } else { | 2979 | } else { |
2685 | lpfc_sli_abort_iocb(phba, pring, 0, 0, rrq->Rxid, | 2980 | cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t); |
2686 | LPFC_CTX_CTX); | ||
2687 | } | 2981 | } |
2688 | 2982 | lpfc_els_rsp_rpl_acc(phba, cmdsize, cmdiocb, ndlp); | |
2689 | spin_unlock_irq(phba->host->host_lock); | ||
2690 | /* ACCEPT the rrq request */ | ||
2691 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | ||
2692 | 2983 | ||
2693 | return 0; | 2984 | return 0; |
2694 | } | 2985 | } |
@@ -2720,7 +3011,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, | |||
2720 | 3011 | ||
2721 | /* We will only support match on WWPN or WWNN */ | 3012 | /* We will only support match on WWPN or WWNN */ |
2722 | if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) { | 3013 | if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) { |
2723 | return (0); | 3014 | return 0; |
2724 | } | 3015 | } |
2725 | 3016 | ||
2726 | cnt = 0; | 3017 | cnt = 0; |
@@ -2743,9 +3034,10 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, | |||
2743 | (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) { | 3034 | (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) { |
2744 | /* Log back into the node before sending the FARP. */ | 3035 | /* Log back into the node before sending the FARP. */ |
2745 | if (fp->Rflags & FARP_REQUEST_PLOGI) { | 3036 | if (fp->Rflags & FARP_REQUEST_PLOGI) { |
3037 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
2746 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 3038 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
2747 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 3039 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
2748 | lpfc_issue_els_plogi(phba, ndlp, 0); | 3040 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
2749 | } | 3041 | } |
2750 | 3042 | ||
2751 | /* Send a FARP response to that node */ | 3043 | /* Send a FARP response to that node */ |
@@ -2754,7 +3046,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, | |||
2754 | } | 3046 | } |
2755 | } | 3047 | } |
2756 | } | 3048 | } |
2757 | return (0); | 3049 | return 0; |
2758 | } | 3050 | } |
2759 | 3051 | ||
2760 | static int | 3052 | static int |
@@ -2787,47 +3079,89 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba, | |||
2787 | 3079 | ||
2788 | static int | 3080 | static int |
2789 | lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 3081 | lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, |
2790 | struct lpfc_nodelist * ndlp) | 3082 | struct lpfc_nodelist * fan_ndlp) |
2791 | { | 3083 | { |
2792 | struct lpfc_dmabuf *pcmd; | 3084 | struct lpfc_dmabuf *pcmd; |
2793 | uint32_t *lp; | 3085 | uint32_t *lp; |
2794 | IOCB_t *icmd; | 3086 | IOCB_t *icmd; |
2795 | FAN *fp; | ||
2796 | uint32_t cmd, did; | 3087 | uint32_t cmd, did; |
3088 | FAN *fp; | ||
3089 | struct lpfc_nodelist *ndlp, *next_ndlp; | ||
3090 | |||
3091 | /* FAN received */ | ||
3092 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:265 FAN received\n", | ||
3093 | phba->brd_no); | ||
2797 | 3094 | ||
2798 | icmd = &cmdiocb->iocb; | 3095 | icmd = &cmdiocb->iocb; |
2799 | did = icmd->un.elsreq64.remoteID; | 3096 | did = icmd->un.elsreq64.remoteID; |
2800 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 3097 | pcmd = (struct lpfc_dmabuf *)cmdiocb->context2; |
2801 | lp = (uint32_t *) pcmd->virt; | 3098 | lp = (uint32_t *)pcmd->virt; |
2802 | 3099 | ||
2803 | cmd = *lp++; | 3100 | cmd = *lp++; |
2804 | fp = (FAN *) lp; | 3101 | fp = (FAN *)lp; |
2805 | 3102 | ||
2806 | /* FAN received */ | 3103 | /* FAN received; Fan does not have a reply sequence */ |
2807 | |||
2808 | /* ACCEPT the FAN request */ | ||
2809 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | ||
2810 | 3104 | ||
2811 | if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { | 3105 | if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { |
2812 | /* The discovery state machine needs to take a different | 3106 | if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName, |
2813 | * action if this node has switched fabrics | 3107 | sizeof(struct lpfc_name)) != 0) || |
2814 | */ | 3108 | (memcmp(&phba->fc_fabparam.portName, &fp->FportName, |
2815 | if ((memcmp(&fp->FportName, &phba->fc_fabparam.portName, | 3109 | sizeof(struct lpfc_name)) != 0)) { |
2816 | sizeof (struct lpfc_name)) != 0) | 3110 | /* |
2817 | || | 3111 | * This node has switched fabrics. FLOGI is required |
2818 | (memcmp(&fp->FnodeName, &phba->fc_fabparam.nodeName, | 3112 | * Clean up the old rpi's |
2819 | sizeof (struct lpfc_name)) != 0)) { | ||
2820 | /* This node has switched fabrics. An FLOGI is required | ||
2821 | * after the timeout | ||
2822 | */ | 3113 | */ |
2823 | return (0); | 3114 | |
3115 | list_for_each_entry_safe(ndlp, next_ndlp, | ||
3116 | &phba->fc_npr_list, nlp_listp) { | ||
3117 | |||
3118 | if (ndlp->nlp_type & NLP_FABRIC) { | ||
3119 | /* | ||
3120 | * Clean up old Fabric, Nameserver and | ||
3121 | * other NLP_FABRIC logins | ||
3122 | */ | ||
3123 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | ||
3124 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | ||
3125 | /* Fail outstanding I/O now since this | ||
3126 | * device is marked for PLOGI | ||
3127 | */ | ||
3128 | lpfc_unreg_rpi(phba, ndlp); | ||
3129 | } | ||
3130 | } | ||
3131 | |||
3132 | phba->hba_state = LPFC_FLOGI; | ||
3133 | lpfc_set_disctmo(phba); | ||
3134 | lpfc_initial_flogi(phba); | ||
3135 | return 0; | ||
2824 | } | 3136 | } |
3137 | /* Discovery not needed, | ||
3138 | * move the nodes to their original state. | ||
3139 | */ | ||
3140 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, | ||
3141 | nlp_listp) { | ||
2825 | 3142 | ||
2826 | /* Start discovery */ | 3143 | switch (ndlp->nlp_prev_state) { |
3144 | case NLP_STE_UNMAPPED_NODE: | ||
3145 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
3146 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | ||
3147 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | ||
3148 | break; | ||
3149 | |||
3150 | case NLP_STE_MAPPED_NODE: | ||
3151 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
3152 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; | ||
3153 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); | ||
3154 | break; | ||
3155 | |||
3156 | default: | ||
3157 | break; | ||
3158 | } | ||
3159 | } | ||
3160 | |||
3161 | /* Start discovery - this should just do CLEAR_LA */ | ||
2827 | lpfc_disc_start(phba); | 3162 | lpfc_disc_start(phba); |
2828 | } | 3163 | } |
2829 | 3164 | return 0; | |
2830 | return (0); | ||
2831 | } | 3165 | } |
2832 | 3166 | ||
2833 | void | 3167 | void |
@@ -2904,8 +3238,9 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
2904 | 3238 | ||
2905 | if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { | 3239 | if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { |
2906 | struct lpfc_nodelist *ndlp; | 3240 | struct lpfc_nodelist *ndlp; |
2907 | 3241 | spin_unlock_irq(phba->host->host_lock); | |
2908 | ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext); | 3242 | ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext); |
3243 | spin_lock_irq(phba->host->host_lock); | ||
2909 | remote_ID = ndlp->nlp_DID; | 3244 | remote_ID = ndlp->nlp_DID; |
2910 | if (cmd->un.elsreq64.bdl.ulpIoTag32) { | 3245 | if (cmd->un.elsreq64.bdl.ulpIoTag32) { |
2911 | lpfc_sli_issue_abort_iotag32(phba, | 3246 | lpfc_sli_issue_abort_iotag32(phba, |
@@ -2950,7 +3285,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) | |||
2950 | struct lpfc_dmabuf *pcmd; | 3285 | struct lpfc_dmabuf *pcmd; |
2951 | uint32_t *elscmd; | 3286 | uint32_t *elscmd; |
2952 | uint32_t els_command; | 3287 | uint32_t els_command; |
2953 | uint32_t remote_ID; | ||
2954 | 3288 | ||
2955 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 3289 | pring = &phba->sli.ring[LPFC_ELS_RING]; |
2956 | spin_lock_irq(phba->host->host_lock); | 3290 | spin_lock_irq(phba->host->host_lock); |
@@ -2973,18 +3307,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) | |||
2973 | elscmd = (uint32_t *) (pcmd->virt); | 3307 | elscmd = (uint32_t *) (pcmd->virt); |
2974 | els_command = *elscmd; | 3308 | els_command = *elscmd; |
2975 | 3309 | ||
2976 | if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { | ||
2977 | struct lpfc_nodelist *ndlp; | ||
2978 | |||
2979 | ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext); | ||
2980 | remote_ID = ndlp->nlp_DID; | ||
2981 | if (phba->hba_state == LPFC_HBA_READY) { | ||
2982 | continue; | ||
2983 | } | ||
2984 | } else { | ||
2985 | remote_ID = cmd->un.elsreq64.remoteID; | ||
2986 | } | ||
2987 | |||
2988 | list_del(&piocb->list); | 3310 | list_del(&piocb->list); |
2989 | pring->txcmplq_cnt--; | 3311 | pring->txcmplq_cnt--; |
2990 | 3312 | ||
@@ -2995,8 +3317,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) | |||
2995 | spin_unlock_irq(phba->host->host_lock); | 3317 | spin_unlock_irq(phba->host->host_lock); |
2996 | (piocb->iocb_cmpl) (phba, piocb, piocb); | 3318 | (piocb->iocb_cmpl) (phba, piocb, piocb); |
2997 | spin_lock_irq(phba->host->host_lock); | 3319 | spin_lock_irq(phba->host->host_lock); |
2998 | } | 3320 | } else |
2999 | else | ||
3000 | lpfc_sli_release_iocbq(phba, piocb); | 3321 | lpfc_sli_release_iocbq(phba, piocb); |
3001 | } | 3322 | } |
3002 | 3323 | ||
@@ -3010,18 +3331,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) | |||
3010 | elscmd = (uint32_t *) (pcmd->virt); | 3331 | elscmd = (uint32_t *) (pcmd->virt); |
3011 | els_command = *elscmd; | 3332 | els_command = *elscmd; |
3012 | 3333 | ||
3013 | if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { | ||
3014 | struct lpfc_nodelist *ndlp; | ||
3015 | |||
3016 | ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext); | ||
3017 | remote_ID = ndlp->nlp_DID; | ||
3018 | if (phba->hba_state == LPFC_HBA_READY) { | ||
3019 | continue; | ||
3020 | } | ||
3021 | } else { | ||
3022 | remote_ID = cmd->un.elsreq64.remoteID; | ||
3023 | } | ||
3024 | |||
3025 | list_del(&piocb->list); | 3334 | list_del(&piocb->list); |
3026 | pring->txcmplq_cnt--; | 3335 | pring->txcmplq_cnt--; |
3027 | 3336 | ||
@@ -3032,8 +3341,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) | |||
3032 | spin_unlock_irq(phba->host->host_lock); | 3341 | spin_unlock_irq(phba->host->host_lock); |
3033 | (piocb->iocb_cmpl) (phba, piocb, piocb); | 3342 | (piocb->iocb_cmpl) (phba, piocb, piocb); |
3034 | spin_lock_irq(phba->host->host_lock); | 3343 | spin_lock_irq(phba->host->host_lock); |
3035 | } | 3344 | } else |
3036 | else | ||
3037 | lpfc_sli_release_iocbq(phba, piocb); | 3345 | lpfc_sli_release_iocbq(phba, piocb); |
3038 | } | 3346 | } |
3039 | spin_unlock_irq(phba->host->host_lock); | 3347 | spin_unlock_irq(phba->host->host_lock); |
@@ -3105,10 +3413,11 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3105 | } | 3413 | } |
3106 | 3414 | ||
3107 | did = icmd->un.rcvels.remoteID; | 3415 | did = icmd->un.rcvels.remoteID; |
3108 | if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did)) == 0) { | 3416 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); |
3417 | if (!ndlp) { | ||
3109 | /* Cannot find existing Fabric ndlp, so allocate a new one */ | 3418 | /* Cannot find existing Fabric ndlp, so allocate a new one */ |
3110 | if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) | 3419 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
3111 | == 0) { | 3420 | if (!ndlp) { |
3112 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 3421 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
3113 | kfree(mp); | 3422 | kfree(mp); |
3114 | drop_cmd = 1; | 3423 | drop_cmd = 1; |
@@ -3201,10 +3510,6 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3201 | phba->fc_stat.elsRcvFAN++; | 3510 | phba->fc_stat.elsRcvFAN++; |
3202 | lpfc_els_rcv_fan(phba, elsiocb, ndlp); | 3511 | lpfc_els_rcv_fan(phba, elsiocb, ndlp); |
3203 | break; | 3512 | break; |
3204 | case ELS_CMD_RRQ: | ||
3205 | phba->fc_stat.elsRcvRRQ++; | ||
3206 | lpfc_els_rcv_rrq(phba, elsiocb, ndlp); | ||
3207 | break; | ||
3208 | case ELS_CMD_PRLI: | 3513 | case ELS_CMD_PRLI: |
3209 | phba->fc_stat.elsRcvPRLI++; | 3514 | phba->fc_stat.elsRcvPRLI++; |
3210 | if (phba->hba_state < LPFC_DISC_AUTH) { | 3515 | if (phba->hba_state < LPFC_DISC_AUTH) { |
@@ -3213,9 +3518,33 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3213 | } | 3518 | } |
3214 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLI); | 3519 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLI); |
3215 | break; | 3520 | break; |
3521 | case ELS_CMD_LIRR: | ||
3522 | phba->fc_stat.elsRcvLIRR++; | ||
3523 | lpfc_els_rcv_lirr(phba, elsiocb, ndlp); | ||
3524 | if (newnode) { | ||
3525 | mempool_free( ndlp, phba->nlp_mem_pool); | ||
3526 | } | ||
3527 | break; | ||
3528 | case ELS_CMD_RPS: | ||
3529 | phba->fc_stat.elsRcvRPS++; | ||
3530 | lpfc_els_rcv_rps(phba, elsiocb, ndlp); | ||
3531 | if (newnode) { | ||
3532 | mempool_free( ndlp, phba->nlp_mem_pool); | ||
3533 | } | ||
3534 | break; | ||
3535 | case ELS_CMD_RPL: | ||
3536 | phba->fc_stat.elsRcvRPL++; | ||
3537 | lpfc_els_rcv_rpl(phba, elsiocb, ndlp); | ||
3538 | if (newnode) { | ||
3539 | mempool_free( ndlp, phba->nlp_mem_pool); | ||
3540 | } | ||
3541 | break; | ||
3216 | case ELS_CMD_RNID: | 3542 | case ELS_CMD_RNID: |
3217 | phba->fc_stat.elsRcvRNID++; | 3543 | phba->fc_stat.elsRcvRNID++; |
3218 | lpfc_els_rcv_rnid(phba, elsiocb, ndlp); | 3544 | lpfc_els_rcv_rnid(phba, elsiocb, ndlp); |
3545 | if (newnode) { | ||
3546 | mempool_free( ndlp, phba->nlp_mem_pool); | ||
3547 | } | ||
3219 | break; | 3548 | break; |
3220 | default: | 3549 | default: |
3221 | /* Unsupported ELS command, reject */ | 3550 | /* Unsupported ELS command, reject */ |
@@ -3249,8 +3578,9 @@ dropit: | |||
3249 | if (drop_cmd == 1) { | 3578 | if (drop_cmd == 1) { |
3250 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | 3579 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, |
3251 | "%d:0111 Dropping received ELS cmd " | 3580 | "%d:0111 Dropping received ELS cmd " |
3252 | "Data: x%x x%x\n", phba->brd_no, | 3581 | "Data: x%x x%x x%x\n", phba->brd_no, |
3253 | icmd->ulpStatus, icmd->un.ulpWord[4]); | 3582 | icmd->ulpStatus, icmd->un.ulpWord[4], |
3583 | icmd->ulpTimeout); | ||
3254 | phba->fc_stat.elsRcvDrop++; | 3584 | phba->fc_stat.elsRcvDrop++; |
3255 | } | 3585 | } |
3256 | return; | 3586 | return; |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index a1f751e79405..6721e679df62 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -59,6 +59,7 @@ static void lpfc_disc_timeout_handler(struct lpfc_hba *); | |||
59 | static void | 59 | static void |
60 | lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 60 | lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) |
61 | { | 61 | { |
62 | uint8_t *name = (uint8_t *)&ndlp->nlp_portname; | ||
62 | int warn_on = 0; | 63 | int warn_on = 0; |
63 | 64 | ||
64 | spin_lock_irq(phba->host->host_lock); | 65 | spin_lock_irq(phba->host->host_lock); |
@@ -67,6 +68,15 @@ lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
67 | return; | 68 | return; |
68 | } | 69 | } |
69 | 70 | ||
71 | /* | ||
72 | * If a discovery event readded nodev_timer after timer | ||
73 | * firing and before processing the timer, cancel the | ||
74 | * nlp_tmofunc. | ||
75 | */ | ||
76 | spin_unlock_irq(phba->host->host_lock); | ||
77 | del_timer_sync(&ndlp->nlp_tmofunc); | ||
78 | spin_lock_irq(phba->host->host_lock); | ||
79 | |||
70 | ndlp->nlp_flag &= ~NLP_NODEV_TMO; | 80 | ndlp->nlp_flag &= ~NLP_NODEV_TMO; |
71 | 81 | ||
72 | if (ndlp->nlp_sid != NLP_NO_SID) { | 82 | if (ndlp->nlp_sid != NLP_NO_SID) { |
@@ -79,15 +89,23 @@ lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
79 | 89 | ||
80 | if (warn_on) { | 90 | if (warn_on) { |
81 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 91 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
82 | "%d:0203 Nodev timeout on NPort x%x " | 92 | "%d:0203 Nodev timeout on " |
83 | "Data: x%x x%x x%x\n", | 93 | "WWPN %x:%x:%x:%x:%x:%x:%x:%x " |
84 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, | 94 | "NPort x%x Data: x%x x%x x%x\n", |
95 | phba->brd_no, | ||
96 | *name, *(name+1), *(name+2), *(name+3), | ||
97 | *(name+4), *(name+5), *(name+6), *(name+7), | ||
98 | ndlp->nlp_DID, ndlp->nlp_flag, | ||
85 | ndlp->nlp_state, ndlp->nlp_rpi); | 99 | ndlp->nlp_state, ndlp->nlp_rpi); |
86 | } else { | 100 | } else { |
87 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 101 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
88 | "%d:0204 Nodev timeout on NPort x%x " | 102 | "%d:0204 Nodev timeout on " |
89 | "Data: x%x x%x x%x\n", | 103 | "WWPN %x:%x:%x:%x:%x:%x:%x:%x " |
90 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, | 104 | "NPort x%x Data: x%x x%x x%x\n", |
105 | phba->brd_no, | ||
106 | *name, *(name+1), *(name+2), *(name+3), | ||
107 | *(name+4), *(name+5), *(name+6), *(name+7), | ||
108 | ndlp->nlp_DID, ndlp->nlp_flag, | ||
91 | ndlp->nlp_state, ndlp->nlp_rpi); | 109 | ndlp->nlp_state, ndlp->nlp_rpi); |
92 | } | 110 | } |
93 | 111 | ||
@@ -108,7 +126,7 @@ lpfc_work_list_done(struct lpfc_hba * phba) | |||
108 | evt_listp); | 126 | evt_listp); |
109 | spin_unlock_irq(phba->host->host_lock); | 127 | spin_unlock_irq(phba->host->host_lock); |
110 | free_evt = 1; | 128 | free_evt = 1; |
111 | switch(evtp->evt) { | 129 | switch (evtp->evt) { |
112 | case LPFC_EVT_NODEV_TMO: | 130 | case LPFC_EVT_NODEV_TMO: |
113 | ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); | 131 | ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); |
114 | lpfc_process_nodev_timeout(phba, ndlp); | 132 | lpfc_process_nodev_timeout(phba, ndlp); |
@@ -120,11 +138,35 @@ lpfc_work_list_done(struct lpfc_hba * phba) | |||
120 | free_evt = 0; | 138 | free_evt = 0; |
121 | break; | 139 | break; |
122 | case LPFC_EVT_ONLINE: | 140 | case LPFC_EVT_ONLINE: |
123 | *(int *)(evtp->evt_arg1) = lpfc_online(phba); | 141 | if (phba->hba_state < LPFC_LINK_DOWN) |
142 | *(int *)(evtp->evt_arg1) = lpfc_online(phba); | ||
143 | else | ||
144 | *(int *)(evtp->evt_arg1) = 0; | ||
124 | complete((struct completion *)(evtp->evt_arg2)); | 145 | complete((struct completion *)(evtp->evt_arg2)); |
125 | break; | 146 | break; |
126 | case LPFC_EVT_OFFLINE: | 147 | case LPFC_EVT_OFFLINE: |
127 | *(int *)(evtp->evt_arg1) = lpfc_offline(phba); | 148 | if (phba->hba_state >= LPFC_LINK_DOWN) |
149 | lpfc_offline(phba); | ||
150 | lpfc_sli_brdrestart(phba); | ||
151 | *(int *)(evtp->evt_arg1) = | ||
152 | lpfc_sli_brdready(phba,HS_FFRDY | HS_MBRDY); | ||
153 | complete((struct completion *)(evtp->evt_arg2)); | ||
154 | break; | ||
155 | case LPFC_EVT_WARM_START: | ||
156 | if (phba->hba_state >= LPFC_LINK_DOWN) | ||
157 | lpfc_offline(phba); | ||
158 | lpfc_reset_barrier(phba); | ||
159 | lpfc_sli_brdreset(phba); | ||
160 | lpfc_hba_down_post(phba); | ||
161 | *(int *)(evtp->evt_arg1) = | ||
162 | lpfc_sli_brdready(phba, HS_MBRDY); | ||
163 | complete((struct completion *)(evtp->evt_arg2)); | ||
164 | break; | ||
165 | case LPFC_EVT_KILL: | ||
166 | if (phba->hba_state >= LPFC_LINK_DOWN) | ||
167 | lpfc_offline(phba); | ||
168 | *(int *)(evtp->evt_arg1) | ||
169 | = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba); | ||
128 | complete((struct completion *)(evtp->evt_arg2)); | 170 | complete((struct completion *)(evtp->evt_arg2)); |
129 | break; | 171 | break; |
130 | } | 172 | } |
@@ -151,13 +193,13 @@ lpfc_work_done(struct lpfc_hba * phba) | |||
151 | work_hba_events=phba->work_hba_events; | 193 | work_hba_events=phba->work_hba_events; |
152 | spin_unlock_irq(phba->host->host_lock); | 194 | spin_unlock_irq(phba->host->host_lock); |
153 | 195 | ||
154 | if(ha_copy & HA_ERATT) | 196 | if (ha_copy & HA_ERATT) |
155 | lpfc_handle_eratt(phba); | 197 | lpfc_handle_eratt(phba); |
156 | 198 | ||
157 | if(ha_copy & HA_MBATT) | 199 | if (ha_copy & HA_MBATT) |
158 | lpfc_sli_handle_mb_event(phba); | 200 | lpfc_sli_handle_mb_event(phba); |
159 | 201 | ||
160 | if(ha_copy & HA_LATT) | 202 | if (ha_copy & HA_LATT) |
161 | lpfc_handle_latt(phba); | 203 | lpfc_handle_latt(phba); |
162 | 204 | ||
163 | if (work_hba_events & WORKER_DISC_TMO) | 205 | if (work_hba_events & WORKER_DISC_TMO) |
@@ -283,16 +325,20 @@ lpfc_linkdown(struct lpfc_hba * phba) | |||
283 | { | 325 | { |
284 | struct lpfc_sli *psli; | 326 | struct lpfc_sli *psli; |
285 | struct lpfc_nodelist *ndlp, *next_ndlp; | 327 | struct lpfc_nodelist *ndlp, *next_ndlp; |
286 | struct list_head *listp; | 328 | struct list_head *listp, *node_list[7]; |
287 | struct list_head *node_list[7]; | ||
288 | LPFC_MBOXQ_t *mb; | 329 | LPFC_MBOXQ_t *mb; |
289 | int rc, i; | 330 | int rc, i; |
290 | 331 | ||
291 | psli = &phba->sli; | 332 | psli = &phba->sli; |
333 | /* sysfs or selective reset may call this routine to clean up */ | ||
334 | if (phba->hba_state >= LPFC_LINK_DOWN) { | ||
335 | if (phba->hba_state == LPFC_LINK_DOWN) | ||
336 | return 0; | ||
292 | 337 | ||
293 | spin_lock_irq(phba->host->host_lock); | 338 | spin_lock_irq(phba->host->host_lock); |
294 | phba->hba_state = LPFC_LINK_DOWN; | 339 | phba->hba_state = LPFC_LINK_DOWN; |
295 | spin_unlock_irq(phba->host->host_lock); | 340 | spin_unlock_irq(phba->host->host_lock); |
341 | } | ||
296 | 342 | ||
297 | /* Clean up any firmware default rpi's */ | 343 | /* Clean up any firmware default rpi's */ |
298 | if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { | 344 | if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { |
@@ -324,32 +370,19 @@ lpfc_linkdown(struct lpfc_hba * phba) | |||
324 | continue; | 370 | continue; |
325 | 371 | ||
326 | list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { | 372 | list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { |
327 | /* Fabric nodes are not handled thru state machine for | 373 | |
328 | link down */ | 374 | rc = lpfc_disc_state_machine(phba, ndlp, NULL, |
329 | if (ndlp->nlp_type & NLP_FABRIC) { | 375 | NLP_EVT_DEVICE_RECOVERY); |
330 | /* Remove ALL Fabric nodes except Fabric_DID */ | 376 | |
331 | if (ndlp->nlp_DID != Fabric_DID) { | 377 | /* Check config parameter use-adisc or FCP-2 */ |
332 | /* Take it off current list and free */ | 378 | if ((rc != NLP_STE_FREED_NODE) && |
333 | lpfc_nlp_list(phba, ndlp, | 379 | (phba->cfg_use_adisc == 0) && |
334 | NLP_NO_LIST); | 380 | !(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) { |
335 | } | 381 | /* We know we will have to relogin, so |
336 | } | 382 | * unreglogin the rpi right now to fail |
337 | else { | 383 | * any outstanding I/Os quickly. |
338 | 384 | */ | |
339 | rc = lpfc_disc_state_machine(phba, ndlp, NULL, | 385 | lpfc_unreg_rpi(phba, ndlp); |
340 | NLP_EVT_DEVICE_RECOVERY); | ||
341 | |||
342 | /* Check config parameter use-adisc or FCP-2 */ | ||
343 | if ((rc != NLP_STE_FREED_NODE) && | ||
344 | (phba->cfg_use_adisc == 0) && | ||
345 | !(ndlp->nlp_fcp_info & | ||
346 | NLP_FCP_2_DEVICE)) { | ||
347 | /* We know we will have to relogin, so | ||
348 | * unreglogin the rpi right now to fail | ||
349 | * any outstanding I/Os quickly. | ||
350 | */ | ||
351 | lpfc_unreg_rpi(phba, ndlp); | ||
352 | } | ||
353 | } | 386 | } |
354 | } | 387 | } |
355 | } | 388 | } |
@@ -384,13 +417,15 @@ lpfc_linkdown(struct lpfc_hba * phba) | |||
384 | lpfc_can_disctmo(phba); | 417 | lpfc_can_disctmo(phba); |
385 | 418 | ||
386 | /* Must process IOCBs on all rings to handle ABORTed I/Os */ | 419 | /* Must process IOCBs on all rings to handle ABORTed I/Os */ |
387 | return (0); | 420 | return 0; |
388 | } | 421 | } |
389 | 422 | ||
390 | static int | 423 | static int |
391 | lpfc_linkup(struct lpfc_hba * phba) | 424 | lpfc_linkup(struct lpfc_hba * phba) |
392 | { | 425 | { |
393 | struct lpfc_nodelist *ndlp, *next_ndlp; | 426 | struct lpfc_nodelist *ndlp, *next_ndlp; |
427 | struct list_head *listp, *node_list[7]; | ||
428 | int i; | ||
394 | 429 | ||
395 | spin_lock_irq(phba->host->host_lock); | 430 | spin_lock_irq(phba->host->host_lock); |
396 | phba->hba_state = LPFC_LINK_UP; | 431 | phba->hba_state = LPFC_LINK_UP; |
@@ -401,14 +436,33 @@ lpfc_linkup(struct lpfc_hba * phba) | |||
401 | spin_unlock_irq(phba->host->host_lock); | 436 | spin_unlock_irq(phba->host->host_lock); |
402 | 437 | ||
403 | 438 | ||
404 | /* | 439 | node_list[0] = &phba->fc_plogi_list; |
405 | * Clean up old Fabric NLP_FABRIC logins. | 440 | node_list[1] = &phba->fc_adisc_list; |
406 | */ | 441 | node_list[2] = &phba->fc_reglogin_list; |
407 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list, | 442 | node_list[3] = &phba->fc_prli_list; |
408 | nlp_listp) { | 443 | node_list[4] = &phba->fc_nlpunmap_list; |
409 | if (ndlp->nlp_DID == Fabric_DID) { | 444 | node_list[5] = &phba->fc_nlpmap_list; |
410 | /* Take it off current list and free */ | 445 | node_list[6] = &phba->fc_npr_list; |
411 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 446 | for (i = 0; i < 7; i++) { |
447 | listp = node_list[i]; | ||
448 | if (list_empty(listp)) | ||
449 | continue; | ||
450 | |||
451 | list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { | ||
452 | if (phba->fc_flag & FC_LBIT) { | ||
453 | if (ndlp->nlp_type & NLP_FABRIC) { | ||
454 | /* On Linkup its safe to clean up the | ||
455 | * ndlp from Fabric connections. | ||
456 | */ | ||
457 | lpfc_nlp_list(phba, ndlp, | ||
458 | NLP_UNUSED_LIST); | ||
459 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | ||
460 | /* Fail outstanding IO now since device | ||
461 | * is marked for PLOGI. | ||
462 | */ | ||
463 | lpfc_unreg_rpi(phba, ndlp); | ||
464 | } | ||
465 | } | ||
412 | } | 466 | } |
413 | } | 467 | } |
414 | 468 | ||
@@ -462,7 +516,7 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
462 | lpfc_els_disc_plogi(phba); | 516 | lpfc_els_disc_plogi(phba); |
463 | } | 517 | } |
464 | 518 | ||
465 | if(!phba->num_disc_nodes) { | 519 | if (!phba->num_disc_nodes) { |
466 | spin_lock_irq(phba->host->host_lock); | 520 | spin_lock_irq(phba->host->host_lock); |
467 | phba->fc_flag &= ~FC_NDISC_ACTIVE; | 521 | phba->fc_flag &= ~FC_NDISC_ACTIVE; |
468 | spin_unlock_irq(phba->host->host_lock); | 522 | spin_unlock_irq(phba->host->host_lock); |
@@ -504,80 +558,59 @@ out: | |||
504 | } | 558 | } |
505 | 559 | ||
506 | static void | 560 | static void |
507 | lpfc_mbx_cmpl_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 561 | lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
508 | { | 562 | { |
509 | struct lpfc_sli *psli; | 563 | struct lpfc_sli *psli = &phba->sli; |
510 | MAILBOX_t *mb; | 564 | int rc; |
511 | |||
512 | psli = &phba->sli; | ||
513 | mb = &pmb->mb; | ||
514 | /* Check for error */ | ||
515 | if (mb->mbxStatus) { | ||
516 | /* CONFIG_LINK mbox error <mbxStatus> state <hba_state> */ | ||
517 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
518 | "%d:0306 CONFIG_LINK mbxStatus error x%x " | ||
519 | "HBA state x%x\n", | ||
520 | phba->brd_no, mb->mbxStatus, phba->hba_state); | ||
521 | 565 | ||
522 | lpfc_linkdown(phba); | 566 | if (pmb->mb.mbxStatus) |
523 | phba->hba_state = LPFC_HBA_ERROR; | ||
524 | goto out; | 567 | goto out; |
525 | } | ||
526 | 568 | ||
527 | if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { | 569 | mempool_free(pmb, phba->mbox_mem_pool); |
528 | if (phba->fc_topology == TOPOLOGY_LOOP) { | 570 | |
529 | /* If we are public loop and L bit was set */ | 571 | if (phba->fc_topology == TOPOLOGY_LOOP && |
530 | if ((phba->fc_flag & FC_PUBLIC_LOOP) && | 572 | phba->fc_flag & FC_PUBLIC_LOOP && |
531 | !(phba->fc_flag & FC_LBIT)) { | 573 | !(phba->fc_flag & FC_LBIT)) { |
532 | /* Need to wait for FAN - use discovery timer | 574 | /* Need to wait for FAN - use discovery timer |
533 | * for timeout. hba_state is identically | 575 | * for timeout. hba_state is identically |
534 | * LPFC_LOCAL_CFG_LINK while waiting for FAN | 576 | * LPFC_LOCAL_CFG_LINK while waiting for FAN |
535 | */ | 577 | */ |
536 | lpfc_set_disctmo(phba); | 578 | lpfc_set_disctmo(phba); |
537 | mempool_free( pmb, phba->mbox_mem_pool); | 579 | return; |
538 | return; | ||
539 | } | ||
540 | } | 580 | } |
541 | 581 | ||
542 | /* Start discovery by sending a FLOGI hba_state is identically | 582 | /* Start discovery by sending a FLOGI. hba_state is identically |
543 | * LPFC_FLOGI while waiting for FLOGI cmpl | 583 | * LPFC_FLOGI while waiting for FLOGI cmpl |
544 | */ | 584 | */ |
545 | phba->hba_state = LPFC_FLOGI; | 585 | phba->hba_state = LPFC_FLOGI; |
546 | lpfc_set_disctmo(phba); | 586 | lpfc_set_disctmo(phba); |
547 | lpfc_initial_flogi(phba); | 587 | lpfc_initial_flogi(phba); |
548 | mempool_free( pmb, phba->mbox_mem_pool); | 588 | return; |
549 | return; | ||
550 | } | ||
551 | if (phba->hba_state == LPFC_FABRIC_CFG_LINK) { | ||
552 | mempool_free( pmb, phba->mbox_mem_pool); | ||
553 | return; | ||
554 | } | ||
555 | 589 | ||
556 | out: | 590 | out: |
557 | /* CONFIG_LINK bad hba state <hba_state> */ | 591 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
558 | lpfc_printf_log(phba, | 592 | "%d:0306 CONFIG_LINK mbxStatus error x%x " |
559 | KERN_ERR, | 593 | "HBA state x%x\n", |
560 | LOG_DISCOVERY, | 594 | phba->brd_no, pmb->mb.mbxStatus, phba->hba_state); |
595 | |||
596 | lpfc_linkdown(phba); | ||
597 | |||
598 | phba->hba_state = LPFC_HBA_ERROR; | ||
599 | |||
600 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
561 | "%d:0200 CONFIG_LINK bad hba state x%x\n", | 601 | "%d:0200 CONFIG_LINK bad hba state x%x\n", |
562 | phba->brd_no, phba->hba_state); | 602 | phba->brd_no, phba->hba_state); |
563 | 603 | ||
564 | if (phba->hba_state != LPFC_CLEAR_LA) { | 604 | lpfc_clear_la(phba, pmb); |
565 | lpfc_clear_la(phba, pmb); | 605 | pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; |
566 | pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la; | 606 | rc = lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); |
567 | if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)) | 607 | if (rc == MBX_NOT_FINISHED) { |
568 | == MBX_NOT_FINISHED) { | 608 | mempool_free(pmb, phba->mbox_mem_pool); |
569 | mempool_free( pmb, phba->mbox_mem_pool); | 609 | lpfc_disc_flush_list(phba); |
570 | lpfc_disc_flush_list(phba); | 610 | psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
571 | psli->ring[(psli->ip_ring)].flag &= | 611 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
572 | ~LPFC_STOP_IOCB_EVENT; | 612 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
573 | psli->ring[(psli->fcp_ring)].flag &= | 613 | phba->hba_state = LPFC_HBA_READY; |
574 | ~LPFC_STOP_IOCB_EVENT; | ||
575 | psli->ring[(psli->next_ring)].flag &= | ||
576 | ~LPFC_STOP_IOCB_EVENT; | ||
577 | phba->hba_state = LPFC_HBA_READY; | ||
578 | } | ||
579 | } else { | ||
580 | mempool_free( pmb, phba->mbox_mem_pool); | ||
581 | } | 614 | } |
582 | return; | 615 | return; |
583 | } | 616 | } |
@@ -650,7 +683,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
650 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 683 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
651 | 684 | ||
652 | spin_lock_irq(phba->host->host_lock); | 685 | spin_lock_irq(phba->host->host_lock); |
653 | switch(la->UlnkSpeed) { | 686 | switch (la->UlnkSpeed) { |
654 | case LA_1GHZ_LINK: | 687 | case LA_1GHZ_LINK: |
655 | phba->fc_linkspeed = LA_1GHZ_LINK; | 688 | phba->fc_linkspeed = LA_1GHZ_LINK; |
656 | break; | 689 | break; |
@@ -731,7 +764,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
731 | if (cfglink_mbox) { | 764 | if (cfglink_mbox) { |
732 | phba->hba_state = LPFC_LOCAL_CFG_LINK; | 765 | phba->hba_state = LPFC_LOCAL_CFG_LINK; |
733 | lpfc_config_link(phba, cfglink_mbox); | 766 | lpfc_config_link(phba, cfglink_mbox); |
734 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_config_link; | 767 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; |
735 | lpfc_sli_issue_mbox(phba, cfglink_mbox, | 768 | lpfc_sli_issue_mbox(phba, cfglink_mbox, |
736 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 769 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
737 | } | 770 | } |
@@ -784,6 +817,13 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
784 | 817 | ||
785 | memcpy(&phba->alpa_map[0], mp->virt, 128); | 818 | memcpy(&phba->alpa_map[0], mp->virt, 128); |
786 | 819 | ||
820 | spin_lock_irq(phba->host->host_lock); | ||
821 | if (la->pb) | ||
822 | phba->fc_flag |= FC_BYPASSED_MODE; | ||
823 | else | ||
824 | phba->fc_flag &= ~FC_BYPASSED_MODE; | ||
825 | spin_unlock_irq(phba->host->host_lock); | ||
826 | |||
787 | if (((phba->fc_eventTag + 1) < la->eventTag) || | 827 | if (((phba->fc_eventTag + 1) < la->eventTag) || |
788 | (phba->fc_eventTag == la->eventTag)) { | 828 | (phba->fc_eventTag == la->eventTag)) { |
789 | phba->fc_stat.LinkMultiEvent++; | 829 | phba->fc_stat.LinkMultiEvent++; |
@@ -904,32 +944,36 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
904 | */ | 944 | */ |
905 | lpfc_issue_els_scr(phba, SCR_DID, 0); | 945 | lpfc_issue_els_scr(phba, SCR_DID, 0); |
906 | 946 | ||
907 | /* Allocate a new node instance. If the pool is empty, just | 947 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); |
908 | * start the discovery process and skip the Nameserver login | 948 | if (!ndlp) { |
909 | * process. This is attempted again later on. Otherwise, issue | 949 | /* Allocate a new node instance. If the pool is empty, |
910 | * a Port Login (PLOGI) to the NameServer | 950 | * start the discovery process and skip the Nameserver |
911 | */ | 951 | * login process. This is attempted again later on. |
912 | if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) | 952 | * Otherwise, issue a Port Login (PLOGI) to NameServer. |
913 | == 0) { | 953 | */ |
914 | lpfc_disc_start(phba); | 954 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); |
915 | } else { | 955 | if (!ndlp) { |
916 | lpfc_nlp_init(phba, ndlp, NameServer_DID); | 956 | lpfc_disc_start(phba); |
917 | ndlp->nlp_type |= NLP_FABRIC; | 957 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
918 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 958 | kfree(mp); |
919 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 959 | mempool_free( pmb, phba->mbox_mem_pool); |
920 | lpfc_issue_els_plogi(phba, ndlp, 0); | 960 | return; |
921 | if (phba->cfg_fdmi_on) { | 961 | } else { |
922 | if ((ndlp_fdmi = mempool_alloc( | 962 | lpfc_nlp_init(phba, ndlp, NameServer_DID); |
923 | phba->nlp_mem_pool, | 963 | ndlp->nlp_type |= NLP_FABRIC; |
924 | GFP_KERNEL))) { | 964 | } |
925 | lpfc_nlp_init(phba, ndlp_fdmi, | 965 | } |
926 | FDMI_DID); | 966 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
927 | ndlp_fdmi->nlp_type |= NLP_FABRIC; | 967 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
928 | ndlp_fdmi->nlp_state = | 968 | lpfc_issue_els_plogi(phba, NameServer_DID, 0); |
929 | NLP_STE_PLOGI_ISSUE; | 969 | if (phba->cfg_fdmi_on) { |
930 | lpfc_issue_els_plogi(phba, ndlp_fdmi, | 970 | ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, |
931 | 0); | 971 | GFP_KERNEL); |
932 | } | 972 | if (ndlp_fdmi) { |
973 | lpfc_nlp_init(phba, ndlp_fdmi, FDMI_DID); | ||
974 | ndlp_fdmi->nlp_type |= NLP_FABRIC; | ||
975 | ndlp_fdmi->nlp_state = NLP_STE_PLOGI_ISSUE; | ||
976 | lpfc_issue_els_plogi(phba, FDMI_DID, 0); | ||
933 | } | 977 | } |
934 | } | 978 | } |
935 | } | 979 | } |
@@ -937,7 +981,6 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
937 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 981 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
938 | kfree(mp); | 982 | kfree(mp); |
939 | mempool_free( pmb, phba->mbox_mem_pool); | 983 | mempool_free( pmb, phba->mbox_mem_pool); |
940 | |||
941 | return; | 984 | return; |
942 | } | 985 | } |
943 | 986 | ||
@@ -1070,12 +1113,12 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1070 | 1113 | ||
1071 | psli = &phba->sli; | 1114 | psli = &phba->sli; |
1072 | /* Sanity check to ensure we are not moving to / from the same list */ | 1115 | /* Sanity check to ensure we are not moving to / from the same list */ |
1073 | if ((nlp->nlp_flag & NLP_LIST_MASK) == list) { | 1116 | if ((nlp->nlp_flag & NLP_LIST_MASK) == list) |
1074 | if (list != NLP_NO_LIST) | 1117 | if (list != NLP_NO_LIST) |
1075 | return(0); | 1118 | return 0; |
1076 | } | ||
1077 | 1119 | ||
1078 | switch(nlp->nlp_flag & NLP_LIST_MASK) { | 1120 | spin_lock_irq(phba->host->host_lock); |
1121 | switch (nlp->nlp_flag & NLP_LIST_MASK) { | ||
1079 | case NLP_NO_LIST: /* Not on any list */ | 1122 | case NLP_NO_LIST: /* Not on any list */ |
1080 | break; | 1123 | break; |
1081 | case NLP_UNUSED_LIST: | 1124 | case NLP_UNUSED_LIST: |
@@ -1101,10 +1144,8 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1101 | case NLP_UNMAPPED_LIST: | 1144 | case NLP_UNMAPPED_LIST: |
1102 | phba->fc_unmap_cnt--; | 1145 | phba->fc_unmap_cnt--; |
1103 | list_del(&nlp->nlp_listp); | 1146 | list_del(&nlp->nlp_listp); |
1104 | spin_lock_irq(phba->host->host_lock); | ||
1105 | nlp->nlp_flag &= ~NLP_TGT_NO_SCSIID; | 1147 | nlp->nlp_flag &= ~NLP_TGT_NO_SCSIID; |
1106 | nlp->nlp_type &= ~NLP_FC_NODE; | 1148 | nlp->nlp_type &= ~NLP_FC_NODE; |
1107 | spin_unlock_irq(phba->host->host_lock); | ||
1108 | phba->nport_event_cnt++; | 1149 | phba->nport_event_cnt++; |
1109 | if (nlp->rport) | 1150 | if (nlp->rport) |
1110 | rport_del = unmapped; | 1151 | rport_del = unmapped; |
@@ -1122,19 +1163,14 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1122 | /* Stop delay tmo if taking node off NPR list */ | 1163 | /* Stop delay tmo if taking node off NPR list */ |
1123 | if ((nlp->nlp_flag & NLP_DELAY_TMO) && | 1164 | if ((nlp->nlp_flag & NLP_DELAY_TMO) && |
1124 | (list != NLP_NPR_LIST)) { | 1165 | (list != NLP_NPR_LIST)) { |
1125 | spin_lock_irq(phba->host->host_lock); | ||
1126 | nlp->nlp_flag &= ~NLP_DELAY_TMO; | ||
1127 | spin_unlock_irq(phba->host->host_lock); | 1166 | spin_unlock_irq(phba->host->host_lock); |
1128 | del_timer_sync(&nlp->nlp_delayfunc); | 1167 | lpfc_cancel_retry_delay_tmo(phba, nlp); |
1129 | if (!list_empty(&nlp->els_retry_evt.evt_listp)) | 1168 | spin_lock_irq(phba->host->host_lock); |
1130 | list_del_init(&nlp->els_retry_evt.evt_listp); | ||
1131 | } | 1169 | } |
1132 | break; | 1170 | break; |
1133 | } | 1171 | } |
1134 | 1172 | ||
1135 | spin_lock_irq(phba->host->host_lock); | ||
1136 | nlp->nlp_flag &= ~NLP_LIST_MASK; | 1173 | nlp->nlp_flag &= ~NLP_LIST_MASK; |
1137 | spin_unlock_irq(phba->host->host_lock); | ||
1138 | 1174 | ||
1139 | /* Add NPort <did> to <num> list */ | 1175 | /* Add NPort <did> to <num> list */ |
1140 | lpfc_printf_log(phba, | 1176 | lpfc_printf_log(phba, |
@@ -1144,48 +1180,40 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1144 | phba->brd_no, | 1180 | phba->brd_no, |
1145 | nlp->nlp_DID, list, nlp->nlp_flag); | 1181 | nlp->nlp_DID, list, nlp->nlp_flag); |
1146 | 1182 | ||
1147 | switch(list) { | 1183 | switch (list) { |
1148 | case NLP_NO_LIST: /* No list, just remove it */ | 1184 | case NLP_NO_LIST: /* No list, just remove it */ |
1185 | spin_unlock_irq(phba->host->host_lock); | ||
1149 | lpfc_nlp_remove(phba, nlp); | 1186 | lpfc_nlp_remove(phba, nlp); |
1187 | spin_lock_irq(phba->host->host_lock); | ||
1150 | /* as node removed - stop further transport calls */ | 1188 | /* as node removed - stop further transport calls */ |
1151 | rport_del = none; | 1189 | rport_del = none; |
1152 | break; | 1190 | break; |
1153 | case NLP_UNUSED_LIST: | 1191 | case NLP_UNUSED_LIST: |
1154 | spin_lock_irq(phba->host->host_lock); | ||
1155 | nlp->nlp_flag |= list; | 1192 | nlp->nlp_flag |= list; |
1156 | spin_unlock_irq(phba->host->host_lock); | ||
1157 | /* Put it at the end of the unused list */ | 1193 | /* Put it at the end of the unused list */ |
1158 | list_add_tail(&nlp->nlp_listp, &phba->fc_unused_list); | 1194 | list_add_tail(&nlp->nlp_listp, &phba->fc_unused_list); |
1159 | phba->fc_unused_cnt++; | 1195 | phba->fc_unused_cnt++; |
1160 | break; | 1196 | break; |
1161 | case NLP_PLOGI_LIST: | 1197 | case NLP_PLOGI_LIST: |
1162 | spin_lock_irq(phba->host->host_lock); | ||
1163 | nlp->nlp_flag |= list; | 1198 | nlp->nlp_flag |= list; |
1164 | spin_unlock_irq(phba->host->host_lock); | ||
1165 | /* Put it at the end of the plogi list */ | 1199 | /* Put it at the end of the plogi list */ |
1166 | list_add_tail(&nlp->nlp_listp, &phba->fc_plogi_list); | 1200 | list_add_tail(&nlp->nlp_listp, &phba->fc_plogi_list); |
1167 | phba->fc_plogi_cnt++; | 1201 | phba->fc_plogi_cnt++; |
1168 | break; | 1202 | break; |
1169 | case NLP_ADISC_LIST: | 1203 | case NLP_ADISC_LIST: |
1170 | spin_lock_irq(phba->host->host_lock); | ||
1171 | nlp->nlp_flag |= list; | 1204 | nlp->nlp_flag |= list; |
1172 | spin_unlock_irq(phba->host->host_lock); | ||
1173 | /* Put it at the end of the adisc list */ | 1205 | /* Put it at the end of the adisc list */ |
1174 | list_add_tail(&nlp->nlp_listp, &phba->fc_adisc_list); | 1206 | list_add_tail(&nlp->nlp_listp, &phba->fc_adisc_list); |
1175 | phba->fc_adisc_cnt++; | 1207 | phba->fc_adisc_cnt++; |
1176 | break; | 1208 | break; |
1177 | case NLP_REGLOGIN_LIST: | 1209 | case NLP_REGLOGIN_LIST: |
1178 | spin_lock_irq(phba->host->host_lock); | ||
1179 | nlp->nlp_flag |= list; | 1210 | nlp->nlp_flag |= list; |
1180 | spin_unlock_irq(phba->host->host_lock); | ||
1181 | /* Put it at the end of the reglogin list */ | 1211 | /* Put it at the end of the reglogin list */ |
1182 | list_add_tail(&nlp->nlp_listp, &phba->fc_reglogin_list); | 1212 | list_add_tail(&nlp->nlp_listp, &phba->fc_reglogin_list); |
1183 | phba->fc_reglogin_cnt++; | 1213 | phba->fc_reglogin_cnt++; |
1184 | break; | 1214 | break; |
1185 | case NLP_PRLI_LIST: | 1215 | case NLP_PRLI_LIST: |
1186 | spin_lock_irq(phba->host->host_lock); | ||
1187 | nlp->nlp_flag |= list; | 1216 | nlp->nlp_flag |= list; |
1188 | spin_unlock_irq(phba->host->host_lock); | ||
1189 | /* Put it at the end of the prli list */ | 1217 | /* Put it at the end of the prli list */ |
1190 | list_add_tail(&nlp->nlp_listp, &phba->fc_prli_list); | 1218 | list_add_tail(&nlp->nlp_listp, &phba->fc_prli_list); |
1191 | phba->fc_prli_cnt++; | 1219 | phba->fc_prli_cnt++; |
@@ -1194,19 +1222,17 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1194 | rport_add = unmapped; | 1222 | rport_add = unmapped; |
1195 | /* ensure all vestiges of "mapped" significance are gone */ | 1223 | /* ensure all vestiges of "mapped" significance are gone */ |
1196 | nlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); | 1224 | nlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); |
1197 | spin_lock_irq(phba->host->host_lock); | ||
1198 | nlp->nlp_flag |= list; | 1225 | nlp->nlp_flag |= list; |
1199 | spin_unlock_irq(phba->host->host_lock); | ||
1200 | /* Put it at the end of the unmap list */ | 1226 | /* Put it at the end of the unmap list */ |
1201 | list_add_tail(&nlp->nlp_listp, &phba->fc_nlpunmap_list); | 1227 | list_add_tail(&nlp->nlp_listp, &phba->fc_nlpunmap_list); |
1202 | phba->fc_unmap_cnt++; | 1228 | phba->fc_unmap_cnt++; |
1203 | phba->nport_event_cnt++; | 1229 | phba->nport_event_cnt++; |
1204 | /* stop nodev tmo if running */ | 1230 | /* stop nodev tmo if running */ |
1205 | if (nlp->nlp_flag & NLP_NODEV_TMO) { | 1231 | if (nlp->nlp_flag & NLP_NODEV_TMO) { |
1206 | spin_lock_irq(phba->host->host_lock); | ||
1207 | nlp->nlp_flag &= ~NLP_NODEV_TMO; | 1232 | nlp->nlp_flag &= ~NLP_NODEV_TMO; |
1208 | spin_unlock_irq(phba->host->host_lock); | 1233 | spin_unlock_irq(phba->host->host_lock); |
1209 | del_timer_sync(&nlp->nlp_tmofunc); | 1234 | del_timer_sync(&nlp->nlp_tmofunc); |
1235 | spin_lock_irq(phba->host->host_lock); | ||
1210 | if (!list_empty(&nlp->nodev_timeout_evt.evt_listp)) | 1236 | if (!list_empty(&nlp->nodev_timeout_evt.evt_listp)) |
1211 | list_del_init(&nlp->nodev_timeout_evt. | 1237 | list_del_init(&nlp->nodev_timeout_evt. |
1212 | evt_listp); | 1238 | evt_listp); |
@@ -1216,9 +1242,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1216 | break; | 1242 | break; |
1217 | case NLP_MAPPED_LIST: | 1243 | case NLP_MAPPED_LIST: |
1218 | rport_add = mapped; | 1244 | rport_add = mapped; |
1219 | spin_lock_irq(phba->host->host_lock); | ||
1220 | nlp->nlp_flag |= list; | 1245 | nlp->nlp_flag |= list; |
1221 | spin_unlock_irq(phba->host->host_lock); | ||
1222 | /* Put it at the end of the map list */ | 1246 | /* Put it at the end of the map list */ |
1223 | list_add_tail(&nlp->nlp_listp, &phba->fc_nlpmap_list); | 1247 | list_add_tail(&nlp->nlp_listp, &phba->fc_nlpmap_list); |
1224 | phba->fc_map_cnt++; | 1248 | phba->fc_map_cnt++; |
@@ -1226,7 +1250,9 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1226 | /* stop nodev tmo if running */ | 1250 | /* stop nodev tmo if running */ |
1227 | if (nlp->nlp_flag & NLP_NODEV_TMO) { | 1251 | if (nlp->nlp_flag & NLP_NODEV_TMO) { |
1228 | nlp->nlp_flag &= ~NLP_NODEV_TMO; | 1252 | nlp->nlp_flag &= ~NLP_NODEV_TMO; |
1253 | spin_unlock_irq(phba->host->host_lock); | ||
1229 | del_timer_sync(&nlp->nlp_tmofunc); | 1254 | del_timer_sync(&nlp->nlp_tmofunc); |
1255 | spin_lock_irq(phba->host->host_lock); | ||
1230 | if (!list_empty(&nlp->nodev_timeout_evt.evt_listp)) | 1256 | if (!list_empty(&nlp->nodev_timeout_evt.evt_listp)) |
1231 | list_del_init(&nlp->nodev_timeout_evt. | 1257 | list_del_init(&nlp->nodev_timeout_evt. |
1232 | evt_listp); | 1258 | evt_listp); |
@@ -1234,33 +1260,24 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1234 | } | 1260 | } |
1235 | break; | 1261 | break; |
1236 | case NLP_NPR_LIST: | 1262 | case NLP_NPR_LIST: |
1237 | spin_lock_irq(phba->host->host_lock); | ||
1238 | nlp->nlp_flag |= list; | 1263 | nlp->nlp_flag |= list; |
1239 | spin_unlock_irq(phba->host->host_lock); | ||
1240 | /* Put it at the end of the npr list */ | 1264 | /* Put it at the end of the npr list */ |
1241 | list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list); | 1265 | list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list); |
1242 | phba->fc_npr_cnt++; | 1266 | phba->fc_npr_cnt++; |
1243 | 1267 | ||
1244 | /* | 1268 | if (!(nlp->nlp_flag & NLP_NODEV_TMO)) |
1245 | * Sanity check for Fabric entity. | ||
1246 | * Set nodev_tmo for NPR state, for Fabric use 1 sec. | ||
1247 | */ | ||
1248 | if (nlp->nlp_type & NLP_FABRIC) { | ||
1249 | mod_timer(&nlp->nlp_tmofunc, jiffies + HZ); | ||
1250 | } | ||
1251 | else { | ||
1252 | mod_timer(&nlp->nlp_tmofunc, | 1269 | mod_timer(&nlp->nlp_tmofunc, |
1253 | jiffies + HZ * phba->cfg_nodev_tmo); | 1270 | jiffies + HZ * phba->cfg_nodev_tmo); |
1254 | } | 1271 | |
1255 | spin_lock_irq(phba->host->host_lock); | ||
1256 | nlp->nlp_flag |= NLP_NODEV_TMO; | 1272 | nlp->nlp_flag |= NLP_NODEV_TMO; |
1257 | nlp->nlp_flag &= ~NLP_RCV_PLOGI; | 1273 | nlp->nlp_flag &= ~NLP_RCV_PLOGI; |
1258 | spin_unlock_irq(phba->host->host_lock); | ||
1259 | break; | 1274 | break; |
1260 | case NLP_JUST_DQ: | 1275 | case NLP_JUST_DQ: |
1261 | break; | 1276 | break; |
1262 | } | 1277 | } |
1263 | 1278 | ||
1279 | spin_unlock_irq(phba->host->host_lock); | ||
1280 | |||
1264 | /* | 1281 | /* |
1265 | * We make all the calls into the transport after we have | 1282 | * We make all the calls into the transport after we have |
1266 | * moved the node between lists. This so that we don't | 1283 | * moved the node between lists. This so that we don't |
@@ -1303,7 +1320,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1303 | } | 1320 | } |
1304 | } | 1321 | } |
1305 | } | 1322 | } |
1306 | return (0); | 1323 | return 0; |
1307 | } | 1324 | } |
1308 | 1325 | ||
1309 | /* | 1326 | /* |
@@ -1314,7 +1331,15 @@ lpfc_set_disctmo(struct lpfc_hba * phba) | |||
1314 | { | 1331 | { |
1315 | uint32_t tmo; | 1332 | uint32_t tmo; |
1316 | 1333 | ||
1317 | tmo = ((phba->fc_ratov * 2) + 1); | 1334 | if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { |
1335 | /* For FAN, timeout should be greater then edtov */ | ||
1336 | tmo = (((phba->fc_edtov + 999) / 1000) + 1); | ||
1337 | } else { | ||
1338 | /* Normal discovery timeout should be > then ELS/CT timeout | ||
1339 | * FC spec states we need 3 * ratov for CT requests | ||
1340 | */ | ||
1341 | tmo = ((phba->fc_ratov * 3) + 3); | ||
1342 | } | ||
1318 | 1343 | ||
1319 | mod_timer(&phba->fc_disctmo, jiffies + HZ * tmo); | 1344 | mod_timer(&phba->fc_disctmo, jiffies + HZ * tmo); |
1320 | spin_lock_irq(phba->host->host_lock); | 1345 | spin_lock_irq(phba->host->host_lock); |
@@ -1354,7 +1379,7 @@ lpfc_can_disctmo(struct lpfc_hba * phba) | |||
1354 | phba->brd_no, phba->hba_state, phba->fc_flag, | 1379 | phba->brd_no, phba->hba_state, phba->fc_flag, |
1355 | phba->fc_plogi_cnt, phba->fc_adisc_cnt); | 1380 | phba->fc_plogi_cnt, phba->fc_adisc_cnt); |
1356 | 1381 | ||
1357 | return (0); | 1382 | return 0; |
1358 | } | 1383 | } |
1359 | 1384 | ||
1360 | /* | 1385 | /* |
@@ -1375,11 +1400,11 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, | |||
1375 | switch (icmd->ulpCommand) { | 1400 | switch (icmd->ulpCommand) { |
1376 | case CMD_GEN_REQUEST64_CR: | 1401 | case CMD_GEN_REQUEST64_CR: |
1377 | if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) | 1402 | if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) |
1378 | return (1); | 1403 | return 1; |
1379 | case CMD_ELS_REQUEST64_CR: | 1404 | case CMD_ELS_REQUEST64_CR: |
1380 | case CMD_XMIT_ELS_RSP64_CX: | 1405 | case CMD_XMIT_ELS_RSP64_CX: |
1381 | if (iocb->context1 == (uint8_t *) ndlp) | 1406 | if (iocb->context1 == (uint8_t *) ndlp) |
1382 | return (1); | 1407 | return 1; |
1383 | } | 1408 | } |
1384 | } else if (pring->ringno == psli->ip_ring) { | 1409 | } else if (pring->ringno == psli->ip_ring) { |
1385 | 1410 | ||
@@ -1387,15 +1412,15 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, | |||
1387 | /* Skip match check if waiting to relogin to FCP target */ | 1412 | /* Skip match check if waiting to relogin to FCP target */ |
1388 | if ((ndlp->nlp_type & NLP_FCP_TARGET) && | 1413 | if ((ndlp->nlp_type & NLP_FCP_TARGET) && |
1389 | (ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1414 | (ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1390 | return (0); | 1415 | return 0; |
1391 | } | 1416 | } |
1392 | if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) { | 1417 | if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) { |
1393 | return (1); | 1418 | return 1; |
1394 | } | 1419 | } |
1395 | } else if (pring->ringno == psli->next_ring) { | 1420 | } else if (pring->ringno == psli->next_ring) { |
1396 | 1421 | ||
1397 | } | 1422 | } |
1398 | return (0); | 1423 | return 0; |
1399 | } | 1424 | } |
1400 | 1425 | ||
1401 | /* | 1426 | /* |
@@ -1456,7 +1481,7 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1456 | 1481 | ||
1457 | } | 1482 | } |
1458 | } | 1483 | } |
1459 | return (0); | 1484 | return 0; |
1460 | } | 1485 | } |
1461 | 1486 | ||
1462 | /* | 1487 | /* |
@@ -1547,6 +1572,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1547 | spin_unlock_irq(phba->host->host_lock); | 1572 | spin_unlock_irq(phba->host->host_lock); |
1548 | del_timer_sync(&ndlp->nlp_tmofunc); | 1573 | del_timer_sync(&ndlp->nlp_tmofunc); |
1549 | 1574 | ||
1575 | ndlp->nlp_last_elscmd = 0; | ||
1550 | del_timer_sync(&ndlp->nlp_delayfunc); | 1576 | del_timer_sync(&ndlp->nlp_delayfunc); |
1551 | 1577 | ||
1552 | if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp)) | 1578 | if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp)) |
@@ -1556,7 +1582,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1556 | 1582 | ||
1557 | lpfc_unreg_rpi(phba, ndlp); | 1583 | lpfc_unreg_rpi(phba, ndlp); |
1558 | 1584 | ||
1559 | return (0); | 1585 | return 0; |
1560 | } | 1586 | } |
1561 | 1587 | ||
1562 | /* | 1588 | /* |
@@ -1579,24 +1605,18 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1579 | 1605 | ||
1580 | 1606 | ||
1581 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 1607 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
1582 | spin_lock_irq(phba->host->host_lock); | 1608 | lpfc_cancel_retry_delay_tmo(phba, ndlp); |
1583 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | ||
1584 | spin_unlock_irq(phba->host->host_lock); | ||
1585 | del_timer_sync(&ndlp->nlp_delayfunc); | ||
1586 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | ||
1587 | list_del_init(&ndlp->els_retry_evt.evt_listp); | ||
1588 | } | 1609 | } |
1589 | 1610 | ||
1590 | if (ndlp->nlp_disc_refcnt) { | 1611 | if (ndlp->nlp_disc_refcnt) { |
1591 | spin_lock_irq(phba->host->host_lock); | 1612 | spin_lock_irq(phba->host->host_lock); |
1592 | ndlp->nlp_flag |= NLP_DELAY_REMOVE; | 1613 | ndlp->nlp_flag |= NLP_DELAY_REMOVE; |
1593 | spin_unlock_irq(phba->host->host_lock); | 1614 | spin_unlock_irq(phba->host->host_lock); |
1594 | } | 1615 | } else { |
1595 | else { | ||
1596 | lpfc_freenode(phba, ndlp); | 1616 | lpfc_freenode(phba, ndlp); |
1597 | mempool_free( ndlp, phba->nlp_mem_pool); | 1617 | mempool_free( ndlp, phba->nlp_mem_pool); |
1598 | } | 1618 | } |
1599 | return(0); | 1619 | return 0; |
1600 | } | 1620 | } |
1601 | 1621 | ||
1602 | static int | 1622 | static int |
@@ -1607,20 +1627,20 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) | |||
1607 | D_ID matchdid; | 1627 | D_ID matchdid; |
1608 | 1628 | ||
1609 | if (did == Bcast_DID) | 1629 | if (did == Bcast_DID) |
1610 | return (0); | 1630 | return 0; |
1611 | 1631 | ||
1612 | if (ndlp->nlp_DID == 0) { | 1632 | if (ndlp->nlp_DID == 0) { |
1613 | return (0); | 1633 | return 0; |
1614 | } | 1634 | } |
1615 | 1635 | ||
1616 | /* First check for Direct match */ | 1636 | /* First check for Direct match */ |
1617 | if (ndlp->nlp_DID == did) | 1637 | if (ndlp->nlp_DID == did) |
1618 | return (1); | 1638 | return 1; |
1619 | 1639 | ||
1620 | /* Next check for area/domain identically equals 0 match */ | 1640 | /* Next check for area/domain identically equals 0 match */ |
1621 | mydid.un.word = phba->fc_myDID; | 1641 | mydid.un.word = phba->fc_myDID; |
1622 | if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) { | 1642 | if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) { |
1623 | return (0); | 1643 | return 0; |
1624 | } | 1644 | } |
1625 | 1645 | ||
1626 | matchdid.un.word = did; | 1646 | matchdid.un.word = did; |
@@ -1631,9 +1651,9 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) | |||
1631 | if ((ndlpdid.un.b.domain == 0) && | 1651 | if ((ndlpdid.un.b.domain == 0) && |
1632 | (ndlpdid.un.b.area == 0)) { | 1652 | (ndlpdid.un.b.area == 0)) { |
1633 | if (ndlpdid.un.b.id) | 1653 | if (ndlpdid.un.b.id) |
1634 | return (1); | 1654 | return 1; |
1635 | } | 1655 | } |
1636 | return (0); | 1656 | return 0; |
1637 | } | 1657 | } |
1638 | 1658 | ||
1639 | matchdid.un.word = ndlp->nlp_DID; | 1659 | matchdid.un.word = ndlp->nlp_DID; |
@@ -1642,11 +1662,11 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) | |||
1642 | if ((matchdid.un.b.domain == 0) && | 1662 | if ((matchdid.un.b.domain == 0) && |
1643 | (matchdid.un.b.area == 0)) { | 1663 | (matchdid.un.b.area == 0)) { |
1644 | if (matchdid.un.b.id) | 1664 | if (matchdid.un.b.id) |
1645 | return (1); | 1665 | return 1; |
1646 | } | 1666 | } |
1647 | } | 1667 | } |
1648 | } | 1668 | } |
1649 | return (0); | 1669 | return 0; |
1650 | } | 1670 | } |
1651 | 1671 | ||
1652 | /* Search for a nodelist entry on a specific list */ | 1672 | /* Search for a nodelist entry on a specific list */ |
@@ -1656,6 +1676,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | |||
1656 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1676 | struct lpfc_nodelist *ndlp, *next_ndlp; |
1657 | uint32_t data1; | 1677 | uint32_t data1; |
1658 | 1678 | ||
1679 | spin_lock_irq(phba->host->host_lock); | ||
1659 | if (order & NLP_SEARCH_UNMAPPED) { | 1680 | if (order & NLP_SEARCH_UNMAPPED) { |
1660 | list_for_each_entry_safe(ndlp, next_ndlp, | 1681 | list_for_each_entry_safe(ndlp, next_ndlp, |
1661 | &phba->fc_nlpunmap_list, nlp_listp) { | 1682 | &phba->fc_nlpunmap_list, nlp_listp) { |
@@ -1671,7 +1692,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | |||
1671 | phba->brd_no, | 1692 | phba->brd_no, |
1672 | ndlp, ndlp->nlp_DID, | 1693 | ndlp, ndlp->nlp_DID, |
1673 | ndlp->nlp_flag, data1); | 1694 | ndlp->nlp_flag, data1); |
1674 | return (ndlp); | 1695 | spin_unlock_irq(phba->host->host_lock); |
1696 | return ndlp; | ||
1675 | } | 1697 | } |
1676 | } | 1698 | } |
1677 | } | 1699 | } |
@@ -1692,7 +1714,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | |||
1692 | phba->brd_no, | 1714 | phba->brd_no, |
1693 | ndlp, ndlp->nlp_DID, | 1715 | ndlp, ndlp->nlp_DID, |
1694 | ndlp->nlp_flag, data1); | 1716 | ndlp->nlp_flag, data1); |
1695 | return (ndlp); | 1717 | spin_unlock_irq(phba->host->host_lock); |
1718 | return ndlp; | ||
1696 | } | 1719 | } |
1697 | } | 1720 | } |
1698 | } | 1721 | } |
@@ -1714,7 +1737,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | |||
1714 | phba->brd_no, | 1737 | phba->brd_no, |
1715 | ndlp, ndlp->nlp_DID, | 1738 | ndlp, ndlp->nlp_DID, |
1716 | ndlp->nlp_flag, data1); | 1739 | ndlp->nlp_flag, data1); |
1717 | return (ndlp); | 1740 | spin_unlock_irq(phba->host->host_lock); |
1741 | return ndlp; | ||
1718 | } | 1742 | } |
1719 | } | 1743 | } |
1720 | } | 1744 | } |
@@ -1736,7 +1760,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | |||
1736 | phba->brd_no, | 1760 | phba->brd_no, |
1737 | ndlp, ndlp->nlp_DID, | 1761 | ndlp, ndlp->nlp_DID, |
1738 | ndlp->nlp_flag, data1); | 1762 | ndlp->nlp_flag, data1); |
1739 | return (ndlp); | 1763 | spin_unlock_irq(phba->host->host_lock); |
1764 | return ndlp; | ||
1740 | } | 1765 | } |
1741 | } | 1766 | } |
1742 | } | 1767 | } |
@@ -1758,7 +1783,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | |||
1758 | phba->brd_no, | 1783 | phba->brd_no, |
1759 | ndlp, ndlp->nlp_DID, | 1784 | ndlp, ndlp->nlp_DID, |
1760 | ndlp->nlp_flag, data1); | 1785 | ndlp->nlp_flag, data1); |
1761 | return (ndlp); | 1786 | spin_unlock_irq(phba->host->host_lock); |
1787 | return ndlp; | ||
1762 | } | 1788 | } |
1763 | } | 1789 | } |
1764 | } | 1790 | } |
@@ -1780,7 +1806,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | |||
1780 | phba->brd_no, | 1806 | phba->brd_no, |
1781 | ndlp, ndlp->nlp_DID, | 1807 | ndlp, ndlp->nlp_DID, |
1782 | ndlp->nlp_flag, data1); | 1808 | ndlp->nlp_flag, data1); |
1783 | return (ndlp); | 1809 | spin_unlock_irq(phba->host->host_lock); |
1810 | return ndlp; | ||
1784 | } | 1811 | } |
1785 | } | 1812 | } |
1786 | } | 1813 | } |
@@ -1802,7 +1829,8 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | |||
1802 | phba->brd_no, | 1829 | phba->brd_no, |
1803 | ndlp, ndlp->nlp_DID, | 1830 | ndlp, ndlp->nlp_DID, |
1804 | ndlp->nlp_flag, data1); | 1831 | ndlp->nlp_flag, data1); |
1805 | return (ndlp); | 1832 | spin_unlock_irq(phba->host->host_lock); |
1833 | return ndlp; | ||
1806 | } | 1834 | } |
1807 | } | 1835 | } |
1808 | } | 1836 | } |
@@ -1824,11 +1852,14 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | |||
1824 | phba->brd_no, | 1852 | phba->brd_no, |
1825 | ndlp, ndlp->nlp_DID, | 1853 | ndlp, ndlp->nlp_DID, |
1826 | ndlp->nlp_flag, data1); | 1854 | ndlp->nlp_flag, data1); |
1827 | return (ndlp); | 1855 | spin_unlock_irq(phba->host->host_lock); |
1856 | return ndlp; | ||
1828 | } | 1857 | } |
1829 | } | 1858 | } |
1830 | } | 1859 | } |
1831 | 1860 | ||
1861 | spin_unlock_irq(phba->host->host_lock); | ||
1862 | |||
1832 | /* FIND node did <did> NOT FOUND */ | 1863 | /* FIND node did <did> NOT FOUND */ |
1833 | lpfc_printf_log(phba, | 1864 | lpfc_printf_log(phba, |
1834 | KERN_INFO, | 1865 | KERN_INFO, |
@@ -1846,8 +1877,9 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) | |||
1846 | struct lpfc_nodelist *ndlp; | 1877 | struct lpfc_nodelist *ndlp; |
1847 | uint32_t flg; | 1878 | uint32_t flg; |
1848 | 1879 | ||
1849 | if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did)) == 0) { | 1880 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); |
1850 | if ((phba->hba_state == LPFC_HBA_READY) && | 1881 | if (!ndlp) { |
1882 | if ((phba->fc_flag & FC_RSCN_MODE) && | ||
1851 | ((lpfc_rscn_payload_check(phba, did) == 0))) | 1883 | ((lpfc_rscn_payload_check(phba, did) == 0))) |
1852 | return NULL; | 1884 | return NULL; |
1853 | ndlp = (struct lpfc_nodelist *) | 1885 | ndlp = (struct lpfc_nodelist *) |
@@ -1860,22 +1892,23 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) | |||
1860 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1892 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
1861 | return ndlp; | 1893 | return ndlp; |
1862 | } | 1894 | } |
1863 | if ((phba->hba_state == LPFC_HBA_READY) && | 1895 | if (phba->fc_flag & FC_RSCN_MODE) { |
1864 | (phba->fc_flag & FC_RSCN_MODE)) { | ||
1865 | if (lpfc_rscn_payload_check(phba, did)) { | 1896 | if (lpfc_rscn_payload_check(phba, did)) { |
1866 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1897 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
1867 | } | 1898 | |
1868 | else { | 1899 | /* Since this node is marked for discovery, |
1900 | * delay timeout is not needed. | ||
1901 | */ | ||
1902 | if (ndlp->nlp_flag & NLP_DELAY_TMO) | ||
1903 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | ||
1904 | } else { | ||
1869 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1905 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1870 | ndlp = NULL; | 1906 | ndlp = NULL; |
1871 | } | 1907 | } |
1872 | } | 1908 | } else { |
1873 | else { | ||
1874 | flg = ndlp->nlp_flag & NLP_LIST_MASK; | 1909 | flg = ndlp->nlp_flag & NLP_LIST_MASK; |
1875 | if ((flg == NLP_ADISC_LIST) || | 1910 | if ((flg == NLP_ADISC_LIST) || (flg == NLP_PLOGI_LIST)) |
1876 | (flg == NLP_PLOGI_LIST)) { | ||
1877 | return NULL; | 1911 | return NULL; |
1878 | } | ||
1879 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1912 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1880 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1913 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1881 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 1914 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
@@ -2023,8 +2056,7 @@ lpfc_disc_start(struct lpfc_hba * phba) | |||
2023 | spin_lock_irq(phba->host->host_lock); | 2056 | spin_lock_irq(phba->host->host_lock); |
2024 | phba->fc_flag &= ~FC_RSCN_MODE; | 2057 | phba->fc_flag &= ~FC_RSCN_MODE; |
2025 | spin_unlock_irq(phba->host->host_lock); | 2058 | spin_unlock_irq(phba->host->host_lock); |
2026 | } | 2059 | } else |
2027 | else | ||
2028 | lpfc_els_handle_rscn(phba); | 2060 | lpfc_els_handle_rscn(phba); |
2029 | } | 2061 | } |
2030 | } | 2062 | } |
@@ -2174,7 +2206,7 @@ static void | |||
2174 | lpfc_disc_timeout_handler(struct lpfc_hba *phba) | 2206 | lpfc_disc_timeout_handler(struct lpfc_hba *phba) |
2175 | { | 2207 | { |
2176 | struct lpfc_sli *psli; | 2208 | struct lpfc_sli *psli; |
2177 | struct lpfc_nodelist *ndlp; | 2209 | struct lpfc_nodelist *ndlp, *next_ndlp; |
2178 | LPFC_MBOXQ_t *clearlambox, *initlinkmbox; | 2210 | LPFC_MBOXQ_t *clearlambox, *initlinkmbox; |
2179 | int rc, clrlaerr = 0; | 2211 | int rc, clrlaerr = 0; |
2180 | 2212 | ||
@@ -2201,10 +2233,19 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2201 | "%d:0221 FAN timeout\n", | 2233 | "%d:0221 FAN timeout\n", |
2202 | phba->brd_no); | 2234 | phba->brd_no); |
2203 | 2235 | ||
2204 | /* Forget about FAN, Start discovery by sending a FLOGI | 2236 | /* Start discovery by sending FLOGI, clean up old rpis */ |
2205 | * hba_state is identically LPFC_FLOGI while waiting for FLOGI | 2237 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, |
2206 | * cmpl | 2238 | nlp_listp) { |
2207 | */ | 2239 | if (ndlp->nlp_type & NLP_FABRIC) { |
2240 | /* Clean up the ndlp on Fabric connections */ | ||
2241 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | ||
2242 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | ||
2243 | /* Fail outstanding IO now since device | ||
2244 | * is marked for PLOGI. | ||
2245 | */ | ||
2246 | lpfc_unreg_rpi(phba, ndlp); | ||
2247 | } | ||
2248 | } | ||
2208 | phba->hba_state = LPFC_FLOGI; | 2249 | phba->hba_state = LPFC_FLOGI; |
2209 | lpfc_set_disctmo(phba); | 2250 | lpfc_set_disctmo(phba); |
2210 | lpfc_initial_flogi(phba); | 2251 | lpfc_initial_flogi(phba); |
@@ -2470,11 +2511,57 @@ lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) | |||
2470 | &phba->fc_reglogin_list}; | 2511 | &phba->fc_reglogin_list}; |
2471 | int i; | 2512 | int i; |
2472 | 2513 | ||
2514 | spin_lock_irq(phba->host->host_lock); | ||
2473 | for (i = 0; i < ARRAY_SIZE(lists); i++ ) | 2515 | for (i = 0; i < ARRAY_SIZE(lists); i++ ) |
2474 | list_for_each_entry(ndlp, lists[i], nlp_listp) | 2516 | list_for_each_entry(ndlp, lists[i], nlp_listp) |
2475 | if (ndlp->nlp_rpi == rpi) | 2517 | if (ndlp->nlp_rpi == rpi) { |
2476 | return (ndlp); | 2518 | spin_unlock_irq(phba->host->host_lock); |
2519 | return ndlp; | ||
2520 | } | ||
2521 | spin_unlock_irq(phba->host->host_lock); | ||
2522 | return NULL; | ||
2523 | } | ||
2524 | |||
2525 | /* | ||
2526 | * This routine looks up the ndlp lists | ||
2527 | * for the given WWPN. If WWPN found | ||
2528 | * it return the node list pointer | ||
2529 | * else return NULL. | ||
2530 | */ | ||
2531 | struct lpfc_nodelist * | ||
2532 | lpfc_findnode_wwpn(struct lpfc_hba * phba, uint32_t order, | ||
2533 | struct lpfc_name * wwpn) | ||
2534 | { | ||
2535 | struct lpfc_nodelist *ndlp; | ||
2536 | struct list_head * lists[]={&phba->fc_nlpunmap_list, | ||
2537 | &phba->fc_nlpmap_list, | ||
2538 | &phba->fc_npr_list, | ||
2539 | &phba->fc_plogi_list, | ||
2540 | &phba->fc_adisc_list, | ||
2541 | &phba->fc_reglogin_list, | ||
2542 | &phba->fc_prli_list}; | ||
2543 | uint32_t search[]={NLP_SEARCH_UNMAPPED, | ||
2544 | NLP_SEARCH_MAPPED, | ||
2545 | NLP_SEARCH_NPR, | ||
2546 | NLP_SEARCH_PLOGI, | ||
2547 | NLP_SEARCH_ADISC, | ||
2548 | NLP_SEARCH_REGLOGIN, | ||
2549 | NLP_SEARCH_PRLI}; | ||
2550 | int i; | ||
2477 | 2551 | ||
2552 | spin_lock_irq(phba->host->host_lock); | ||
2553 | for (i = 0; i < ARRAY_SIZE(lists); i++ ) { | ||
2554 | if (!(order & search[i])) | ||
2555 | continue; | ||
2556 | list_for_each_entry(ndlp, lists[i], nlp_listp) { | ||
2557 | if (memcmp(&ndlp->nlp_portname, wwpn, | ||
2558 | sizeof(struct lpfc_name)) == 0) { | ||
2559 | spin_unlock_irq(phba->host->host_lock); | ||
2560 | return ndlp; | ||
2561 | } | ||
2562 | } | ||
2563 | } | ||
2564 | spin_unlock_irq(phba->host->host_lock); | ||
2478 | return NULL; | 2565 | return NULL; |
2479 | } | 2566 | } |
2480 | 2567 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 1ea565e0561f..54d04188f7cc 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -454,10 +454,13 @@ struct serv_parm { /* Structure is in Big Endian format */ | |||
454 | #define ELS_CMD_ADISC 0x52000000 | 454 | #define ELS_CMD_ADISC 0x52000000 |
455 | #define ELS_CMD_FARP 0x54000000 | 455 | #define ELS_CMD_FARP 0x54000000 |
456 | #define ELS_CMD_FARPR 0x55000000 | 456 | #define ELS_CMD_FARPR 0x55000000 |
457 | #define ELS_CMD_RPS 0x56000000 | ||
458 | #define ELS_CMD_RPL 0x57000000 | ||
457 | #define ELS_CMD_FAN 0x60000000 | 459 | #define ELS_CMD_FAN 0x60000000 |
458 | #define ELS_CMD_RSCN 0x61040000 | 460 | #define ELS_CMD_RSCN 0x61040000 |
459 | #define ELS_CMD_SCR 0x62000000 | 461 | #define ELS_CMD_SCR 0x62000000 |
460 | #define ELS_CMD_RNID 0x78000000 | 462 | #define ELS_CMD_RNID 0x78000000 |
463 | #define ELS_CMD_LIRR 0x7A000000 | ||
461 | #else /* __LITTLE_ENDIAN_BITFIELD */ | 464 | #else /* __LITTLE_ENDIAN_BITFIELD */ |
462 | #define ELS_CMD_MASK 0xffff | 465 | #define ELS_CMD_MASK 0xffff |
463 | #define ELS_RSP_MASK 0xff | 466 | #define ELS_RSP_MASK 0xff |
@@ -486,10 +489,13 @@ struct serv_parm { /* Structure is in Big Endian format */ | |||
486 | #define ELS_CMD_ADISC 0x52 | 489 | #define ELS_CMD_ADISC 0x52 |
487 | #define ELS_CMD_FARP 0x54 | 490 | #define ELS_CMD_FARP 0x54 |
488 | #define ELS_CMD_FARPR 0x55 | 491 | #define ELS_CMD_FARPR 0x55 |
492 | #define ELS_CMD_RPS 0x56 | ||
493 | #define ELS_CMD_RPL 0x57 | ||
489 | #define ELS_CMD_FAN 0x60 | 494 | #define ELS_CMD_FAN 0x60 |
490 | #define ELS_CMD_RSCN 0x0461 | 495 | #define ELS_CMD_RSCN 0x0461 |
491 | #define ELS_CMD_SCR 0x62 | 496 | #define ELS_CMD_SCR 0x62 |
492 | #define ELS_CMD_RNID 0x78 | 497 | #define ELS_CMD_RNID 0x78 |
498 | #define ELS_CMD_LIRR 0x7A | ||
493 | #endif | 499 | #endif |
494 | 500 | ||
495 | /* | 501 | /* |
@@ -758,12 +764,40 @@ typedef struct _RNID { /* Structure is in Big Endian format */ | |||
758 | } un; | 764 | } un; |
759 | } RNID; | 765 | } RNID; |
760 | 766 | ||
761 | typedef struct _RRQ { /* Structure is in Big Endian format */ | 767 | typedef struct _RPS { /* Structure is in Big Endian format */ |
762 | uint32_t SID; | 768 | union { |
763 | uint16_t Oxid; | 769 | uint32_t portNum; |
764 | uint16_t Rxid; | 770 | struct lpfc_name portName; |
765 | uint8_t resv[32]; /* optional association hdr */ | 771 | } un; |
766 | } RRQ; | 772 | } RPS; |
773 | |||
774 | typedef struct _RPS_RSP { /* Structure is in Big Endian format */ | ||
775 | uint16_t rsvd1; | ||
776 | uint16_t portStatus; | ||
777 | uint32_t linkFailureCnt; | ||
778 | uint32_t lossSyncCnt; | ||
779 | uint32_t lossSignalCnt; | ||
780 | uint32_t primSeqErrCnt; | ||
781 | uint32_t invalidXmitWord; | ||
782 | uint32_t crcCnt; | ||
783 | } RPS_RSP; | ||
784 | |||
785 | typedef struct _RPL { /* Structure is in Big Endian format */ | ||
786 | uint32_t maxsize; | ||
787 | uint32_t index; | ||
788 | } RPL; | ||
789 | |||
790 | typedef struct _PORT_NUM_BLK { | ||
791 | uint32_t portNum; | ||
792 | uint32_t portID; | ||
793 | struct lpfc_name portName; | ||
794 | } PORT_NUM_BLK; | ||
795 | |||
796 | typedef struct _RPL_RSP { /* Structure is in Big Endian format */ | ||
797 | uint32_t listLen; | ||
798 | uint32_t index; | ||
799 | PORT_NUM_BLK port_num_blk; | ||
800 | } RPL_RSP; | ||
767 | 801 | ||
768 | /* This is used for RSCN command */ | 802 | /* This is used for RSCN command */ |
769 | typedef struct _D_ID { /* Structure is in Big Endian format */ | 803 | typedef struct _D_ID { /* Structure is in Big Endian format */ |
@@ -804,7 +838,6 @@ typedef struct _ELS_PKT { /* Structure is in Big Endian format */ | |||
804 | FARP farp; /* Payload for FARP/ACC */ | 838 | FARP farp; /* Payload for FARP/ACC */ |
805 | FAN fan; /* Payload for FAN */ | 839 | FAN fan; /* Payload for FAN */ |
806 | SCR scr; /* Payload for SCR/ACC */ | 840 | SCR scr; /* Payload for SCR/ACC */ |
807 | RRQ rrq; /* Payload for RRQ */ | ||
808 | RNID rnid; /* Payload for RNID */ | 841 | RNID rnid; /* Payload for RNID */ |
809 | uint8_t pad[128 - 4]; /* Pad out to payload of 128 bytes */ | 842 | uint8_t pad[128 - 4]; /* Pad out to payload of 128 bytes */ |
810 | } un; | 843 | } un; |
@@ -1200,7 +1233,9 @@ typedef struct { /* FireFly BIU registers */ | |||
1200 | #define MBX_SET_MASK 0x20 | 1233 | #define MBX_SET_MASK 0x20 |
1201 | #define MBX_SET_SLIM 0x21 | 1234 | #define MBX_SET_SLIM 0x21 |
1202 | #define MBX_UNREG_D_ID 0x23 | 1235 | #define MBX_UNREG_D_ID 0x23 |
1236 | #define MBX_KILL_BOARD 0x24 | ||
1203 | #define MBX_CONFIG_FARP 0x25 | 1237 | #define MBX_CONFIG_FARP 0x25 |
1238 | #define MBX_BEACON 0x2A | ||
1204 | 1239 | ||
1205 | #define MBX_LOAD_AREA 0x81 | 1240 | #define MBX_LOAD_AREA 0x81 |
1206 | #define MBX_RUN_BIU_DIAG64 0x84 | 1241 | #define MBX_RUN_BIU_DIAG64 0x84 |
@@ -1676,13 +1711,13 @@ typedef struct { | |||
1676 | uint32_t rttov; | 1711 | uint32_t rttov; |
1677 | uint32_t altov; | 1712 | uint32_t altov; |
1678 | uint32_t lmt; | 1713 | uint32_t lmt; |
1679 | #define LMT_RESERVED 0x0 /* Not used */ | 1714 | #define LMT_RESERVED 0x000 /* Not used */ |
1680 | #define LMT_266_10bit 0x1 /* 265.625 Mbaud 10 bit iface */ | 1715 | #define LMT_1Gb 0x004 |
1681 | #define LMT_532_10bit 0x2 /* 531.25 Mbaud 10 bit iface */ | 1716 | #define LMT_2Gb 0x008 |
1682 | #define LMT_1063_20bit 0x3 /* 1062.5 Mbaud 20 bit iface */ | 1717 | #define LMT_4Gb 0x040 |
1683 | #define LMT_1063_10bit 0x4 /* 1062.5 Mbaud 10 bit iface */ | 1718 | #define LMT_8Gb 0x080 |
1684 | #define LMT_2125_10bit 0x8 /* 2125 Mbaud 10 bit iface */ | 1719 | #define LMT_10Gb 0x100 |
1685 | #define LMT_4250_10bit 0x40 /* 4250 Mbaud 10 bit iface */ | 1720 | |
1686 | 1721 | ||
1687 | uint32_t rsvd2; | 1722 | uint32_t rsvd2; |
1688 | uint32_t rsvd3; | 1723 | uint32_t rsvd3; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b7a603a45328..66d5d003555d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -42,7 +42,7 @@ | |||
42 | #include "lpfc_crtn.h" | 42 | #include "lpfc_crtn.h" |
43 | #include "lpfc_version.h" | 43 | #include "lpfc_version.h" |
44 | 44 | ||
45 | static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *); | 45 | static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); |
46 | static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); | 46 | static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); |
47 | static int lpfc_post_rcv_buf(struct lpfc_hba *); | 47 | static int lpfc_post_rcv_buf(struct lpfc_hba *); |
48 | 48 | ||
@@ -161,9 +161,6 @@ lpfc_config_port_prep(struct lpfc_hba * phba) | |||
161 | memcpy(phba->RandomData, (char *)&mb->un.varWords[24], | 161 | memcpy(phba->RandomData, (char *)&mb->un.varWords[24], |
162 | sizeof (phba->RandomData)); | 162 | sizeof (phba->RandomData)); |
163 | 163 | ||
164 | /* Get the default values for Model Name and Description */ | ||
165 | lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc); | ||
166 | |||
167 | /* Get adapter VPD information */ | 164 | /* Get adapter VPD information */ |
168 | pmb->context2 = kmalloc(DMP_RSP_SIZE, GFP_KERNEL); | 165 | pmb->context2 = kmalloc(DMP_RSP_SIZE, GFP_KERNEL); |
169 | if (!pmb->context2) | 166 | if (!pmb->context2) |
@@ -182,16 +179,15 @@ lpfc_config_port_prep(struct lpfc_hba * phba) | |||
182 | "mbxCmd x%x DUMP VPD, mbxStatus x%x\n", | 179 | "mbxCmd x%x DUMP VPD, mbxStatus x%x\n", |
183 | phba->brd_no, | 180 | phba->brd_no, |
184 | mb->mbxCommand, mb->mbxStatus); | 181 | mb->mbxCommand, mb->mbxStatus); |
185 | kfree(lpfc_vpd_data); | 182 | mb->un.varDmp.word_cnt = 0; |
186 | lpfc_vpd_data = NULL; | ||
187 | break; | ||
188 | } | 183 | } |
189 | 184 | if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset) | |
185 | mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset; | ||
190 | lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset, | 186 | lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset, |
191 | mb->un.varDmp.word_cnt); | 187 | mb->un.varDmp.word_cnt); |
192 | offset += mb->un.varDmp.word_cnt; | 188 | offset += mb->un.varDmp.word_cnt; |
193 | } while (mb->un.varDmp.word_cnt); | 189 | } while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE); |
194 | lpfc_parse_vpd(phba, lpfc_vpd_data); | 190 | lpfc_parse_vpd(phba, lpfc_vpd_data, offset); |
195 | 191 | ||
196 | kfree(lpfc_vpd_data); | 192 | kfree(lpfc_vpd_data); |
197 | out_free_context2: | 193 | out_free_context2: |
@@ -327,13 +323,22 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
327 | mb->un.varRdConfig.max_xri + 1; | 323 | mb->un.varRdConfig.max_xri + 1; |
328 | 324 | ||
329 | phba->lmt = mb->un.varRdConfig.lmt; | 325 | phba->lmt = mb->un.varRdConfig.lmt; |
330 | /* HBA is not 4GB capable, or HBA is not 2GB capable, | 326 | |
331 | don't let link speed ask for it */ | 327 | /* Get the default values for Model Name and Description */ |
332 | if ((((phba->lmt & LMT_4250_10bit) != LMT_4250_10bit) && | 328 | lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc); |
333 | (phba->cfg_link_speed > LINK_SPEED_2G)) || | 329 | |
334 | (((phba->lmt & LMT_2125_10bit) != LMT_2125_10bit) && | 330 | if ((phba->cfg_link_speed > LINK_SPEED_10G) |
335 | (phba->cfg_link_speed > LINK_SPEED_1G))) { | 331 | || ((phba->cfg_link_speed == LINK_SPEED_1G) |
336 | /* Reset link speed to auto. 1G/2GB HBA cfg'd for 4G */ | 332 | && !(phba->lmt & LMT_1Gb)) |
333 | || ((phba->cfg_link_speed == LINK_SPEED_2G) | ||
334 | && !(phba->lmt & LMT_2Gb)) | ||
335 | || ((phba->cfg_link_speed == LINK_SPEED_4G) | ||
336 | && !(phba->lmt & LMT_4Gb)) | ||
337 | || ((phba->cfg_link_speed == LINK_SPEED_8G) | ||
338 | && !(phba->lmt & LMT_8Gb)) | ||
339 | || ((phba->cfg_link_speed == LINK_SPEED_10G) | ||
340 | && !(phba->lmt & LMT_10Gb))) { | ||
341 | /* Reset link speed to auto */ | ||
337 | lpfc_printf_log(phba, | 342 | lpfc_printf_log(phba, |
338 | KERN_WARNING, | 343 | KERN_WARNING, |
339 | LOG_LINK_EVENT, | 344 | LOG_LINK_EVENT, |
@@ -464,6 +469,40 @@ lpfc_hba_down_prep(struct lpfc_hba * phba) | |||
464 | 469 | ||
465 | /************************************************************************/ | 470 | /************************************************************************/ |
466 | /* */ | 471 | /* */ |
472 | /* lpfc_hba_down_post */ | ||
473 | /* This routine will do uninitialization after the HBA is reset */ | ||
474 | /* when bringing down the SLI Layer. */ | ||
475 | /* This routine returns 0 on success. Any other return value */ | ||
476 | /* indicates an error. */ | ||
477 | /* */ | ||
478 | /************************************************************************/ | ||
479 | int | ||
480 | lpfc_hba_down_post(struct lpfc_hba * phba) | ||
481 | { | ||
482 | struct lpfc_sli *psli = &phba->sli; | ||
483 | struct lpfc_sli_ring *pring; | ||
484 | struct lpfc_dmabuf *mp, *next_mp; | ||
485 | int i; | ||
486 | |||
487 | /* Cleanup preposted buffers on the ELS ring */ | ||
488 | pring = &psli->ring[LPFC_ELS_RING]; | ||
489 | list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { | ||
490 | list_del(&mp->list); | ||
491 | pring->postbufq_cnt--; | ||
492 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
493 | kfree(mp); | ||
494 | } | ||
495 | |||
496 | for (i = 0; i < psli->num_rings; i++) { | ||
497 | pring = &psli->ring[i]; | ||
498 | lpfc_sli_abort_iocb_ring(phba, pring); | ||
499 | } | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | /************************************************************************/ | ||
505 | /* */ | ||
467 | /* lpfc_handle_eratt */ | 506 | /* lpfc_handle_eratt */ |
468 | /* This routine will handle processing a Host Attention */ | 507 | /* This routine will handle processing a Host Attention */ |
469 | /* Error Status event. This will be initialized */ | 508 | /* Error Status event. This will be initialized */ |
@@ -476,20 +515,6 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
476 | struct lpfc_sli *psli = &phba->sli; | 515 | struct lpfc_sli *psli = &phba->sli; |
477 | struct lpfc_sli_ring *pring; | 516 | struct lpfc_sli_ring *pring; |
478 | 517 | ||
479 | /* | ||
480 | * If a reset is sent to the HBA restore PCI configuration registers. | ||
481 | */ | ||
482 | if ( phba->hba_state == LPFC_INIT_START ) { | ||
483 | mdelay(1); | ||
484 | readl(phba->HCregaddr); /* flush */ | ||
485 | writel(0, phba->HCregaddr); | ||
486 | readl(phba->HCregaddr); /* flush */ | ||
487 | |||
488 | /* Restore PCI cmd register */ | ||
489 | pci_write_config_word(phba->pcidev, | ||
490 | PCI_COMMAND, phba->pci_cfg_value); | ||
491 | } | ||
492 | |||
493 | if (phba->work_hs & HS_FFER6) { | 518 | if (phba->work_hs & HS_FFER6) { |
494 | /* Re-establishing Link */ | 519 | /* Re-establishing Link */ |
495 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, | 520 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, |
@@ -499,6 +524,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
499 | phba->work_status[0], phba->work_status[1]); | 524 | phba->work_status[0], phba->work_status[1]); |
500 | spin_lock_irq(phba->host->host_lock); | 525 | spin_lock_irq(phba->host->host_lock); |
501 | phba->fc_flag |= FC_ESTABLISH_LINK; | 526 | phba->fc_flag |= FC_ESTABLISH_LINK; |
527 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
502 | spin_unlock_irq(phba->host->host_lock); | 528 | spin_unlock_irq(phba->host->host_lock); |
503 | 529 | ||
504 | /* | 530 | /* |
@@ -516,6 +542,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
516 | * attempt to restart it. | 542 | * attempt to restart it. |
517 | */ | 543 | */ |
518 | lpfc_offline(phba); | 544 | lpfc_offline(phba); |
545 | lpfc_sli_brdrestart(phba); | ||
519 | if (lpfc_online(phba) == 0) { /* Initialize the HBA */ | 546 | if (lpfc_online(phba) == 0) { /* Initialize the HBA */ |
520 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | 547 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); |
521 | return; | 548 | return; |
@@ -531,8 +558,10 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
531 | phba->brd_no, phba->work_hs, | 558 | phba->brd_no, phba->work_hs, |
532 | phba->work_status[0], phba->work_status[1]); | 559 | phba->work_status[0], phba->work_status[1]); |
533 | 560 | ||
561 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
534 | lpfc_offline(phba); | 562 | lpfc_offline(phba); |
535 | 563 | phba->hba_state = LPFC_HBA_ERROR; | |
564 | lpfc_hba_down_post(phba); | ||
536 | } | 565 | } |
537 | } | 566 | } |
538 | 567 | ||
@@ -623,7 +652,7 @@ lpfc_handle_latt_err_exit: | |||
623 | /* */ | 652 | /* */ |
624 | /************************************************************************/ | 653 | /************************************************************************/ |
625 | static int | 654 | static int |
626 | lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd) | 655 | lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) |
627 | { | 656 | { |
628 | uint8_t lenlo, lenhi; | 657 | uint8_t lenlo, lenhi; |
629 | uint32_t Length; | 658 | uint32_t Length; |
@@ -642,9 +671,10 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd) | |||
642 | phba->brd_no, | 671 | phba->brd_no, |
643 | (uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2], | 672 | (uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2], |
644 | (uint32_t) vpd[3]); | 673 | (uint32_t) vpd[3]); |
645 | do { | 674 | while (!finished && (index < (len - 4))) { |
646 | switch (vpd[index]) { | 675 | switch (vpd[index]) { |
647 | case 0x82: | 676 | case 0x82: |
677 | case 0x91: | ||
648 | index += 1; | 678 | index += 1; |
649 | lenlo = vpd[index]; | 679 | lenlo = vpd[index]; |
650 | index += 1; | 680 | index += 1; |
@@ -660,7 +690,8 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd) | |||
660 | lenhi = vpd[index]; | 690 | lenhi = vpd[index]; |
661 | index += 1; | 691 | index += 1; |
662 | Length = ((((unsigned short)lenhi) << 8) + lenlo); | 692 | Length = ((((unsigned short)lenhi) << 8) + lenlo); |
663 | 693 | if (Length > len - index) | |
694 | Length = len - index; | ||
664 | while (Length > 0) { | 695 | while (Length > 0) { |
665 | /* Look for Serial Number */ | 696 | /* Look for Serial Number */ |
666 | if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) { | 697 | if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) { |
@@ -754,7 +785,7 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd) | |||
754 | index ++; | 785 | index ++; |
755 | break; | 786 | break; |
756 | } | 787 | } |
757 | } while (!finished && (index < 108)); | 788 | } |
758 | 789 | ||
759 | return(1); | 790 | return(1); |
760 | } | 791 | } |
@@ -765,137 +796,173 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | |||
765 | lpfc_vpd_t *vp; | 796 | lpfc_vpd_t *vp; |
766 | uint16_t dev_id = phba->pcidev->device; | 797 | uint16_t dev_id = phba->pcidev->device; |
767 | uint16_t dev_subid = phba->pcidev->subsystem_device; | 798 | uint16_t dev_subid = phba->pcidev->subsystem_device; |
768 | uint8_t hdrtype = phba->pcidev->hdr_type; | 799 | uint8_t hdrtype; |
769 | char *model_str = ""; | 800 | int max_speed; |
801 | char * ports; | ||
802 | struct { | ||
803 | char * name; | ||
804 | int max_speed; | ||
805 | char * ports; | ||
806 | char * bus; | ||
807 | } m; | ||
808 | |||
809 | pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype); | ||
810 | ports = (hdrtype == 0x80) ? "2-port " : ""; | ||
811 | if (mdp && mdp[0] != '\0' | ||
812 | && descp && descp[0] != '\0') | ||
813 | return; | ||
814 | |||
815 | if (phba->lmt & LMT_10Gb) | ||
816 | max_speed = 10; | ||
817 | else if (phba->lmt & LMT_8Gb) | ||
818 | max_speed = 8; | ||
819 | else if (phba->lmt & LMT_4Gb) | ||
820 | max_speed = 4; | ||
821 | else if (phba->lmt & LMT_2Gb) | ||
822 | max_speed = 2; | ||
823 | else | ||
824 | max_speed = 1; | ||
770 | 825 | ||
771 | vp = &phba->vpd; | 826 | vp = &phba->vpd; |
772 | 827 | ||
773 | switch (dev_id) { | 828 | switch (dev_id) { |
774 | case PCI_DEVICE_ID_FIREFLY: | 829 | case PCI_DEVICE_ID_FIREFLY: |
775 | model_str = "LP6000 1Gb PCI"; | 830 | m = (typeof(m)){"LP6000", max_speed, "", "PCI"}; |
776 | break; | 831 | break; |
777 | case PCI_DEVICE_ID_SUPERFLY: | 832 | case PCI_DEVICE_ID_SUPERFLY: |
778 | if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3) | 833 | if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3) |
779 | model_str = "LP7000 1Gb PCI"; | 834 | m = (typeof(m)){"LP7000", max_speed, "", "PCI"}; |
780 | else | 835 | else |
781 | model_str = "LP7000E 1Gb PCI"; | 836 | m = (typeof(m)){"LP7000E", max_speed, "", "PCI"}; |
782 | break; | 837 | break; |
783 | case PCI_DEVICE_ID_DRAGONFLY: | 838 | case PCI_DEVICE_ID_DRAGONFLY: |
784 | model_str = "LP8000 1Gb PCI"; | 839 | m = (typeof(m)){"LP8000", max_speed, "", "PCI"}; |
785 | break; | 840 | break; |
786 | case PCI_DEVICE_ID_CENTAUR: | 841 | case PCI_DEVICE_ID_CENTAUR: |
787 | if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) | 842 | if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) |
788 | model_str = "LP9002 2Gb PCI"; | 843 | m = (typeof(m)){"LP9002", max_speed, "", "PCI"}; |
789 | else | 844 | else |
790 | model_str = "LP9000 1Gb PCI"; | 845 | m = (typeof(m)){"LP9000", max_speed, "", "PCI"}; |
791 | break; | 846 | break; |
792 | case PCI_DEVICE_ID_RFLY: | 847 | case PCI_DEVICE_ID_RFLY: |
793 | model_str = "LP952 2Gb PCI"; | 848 | m = (typeof(m)){"LP952", max_speed, "", "PCI"}; |
794 | break; | 849 | break; |
795 | case PCI_DEVICE_ID_PEGASUS: | 850 | case PCI_DEVICE_ID_PEGASUS: |
796 | model_str = "LP9802 2Gb PCI-X"; | 851 | m = (typeof(m)){"LP9802", max_speed, "", "PCI-X"}; |
797 | break; | 852 | break; |
798 | case PCI_DEVICE_ID_THOR: | 853 | case PCI_DEVICE_ID_THOR: |
799 | if (hdrtype == 0x80) | 854 | if (hdrtype == 0x80) |
800 | model_str = "LP10000DC 2Gb 2-port PCI-X"; | 855 | m = (typeof(m)){"LP10000DC", |
856 | max_speed, ports, "PCI-X"}; | ||
801 | else | 857 | else |
802 | model_str = "LP10000 2Gb PCI-X"; | 858 | m = (typeof(m)){"LP10000", |
859 | max_speed, ports, "PCI-X"}; | ||
803 | break; | 860 | break; |
804 | case PCI_DEVICE_ID_VIPER: | 861 | case PCI_DEVICE_ID_VIPER: |
805 | model_str = "LPX1000 10Gb PCI-X"; | 862 | m = (typeof(m)){"LPX1000", max_speed, "", "PCI-X"}; |
806 | break; | 863 | break; |
807 | case PCI_DEVICE_ID_PFLY: | 864 | case PCI_DEVICE_ID_PFLY: |
808 | model_str = "LP982 2Gb PCI-X"; | 865 | m = (typeof(m)){"LP982", max_speed, "", "PCI-X"}; |
809 | break; | 866 | break; |
810 | case PCI_DEVICE_ID_TFLY: | 867 | case PCI_DEVICE_ID_TFLY: |
811 | if (hdrtype == 0x80) | 868 | if (hdrtype == 0x80) |
812 | model_str = "LP1050DC 2Gb 2-port PCI-X"; | 869 | m = (typeof(m)){"LP1050DC", max_speed, ports, "PCI-X"}; |
813 | else | 870 | else |
814 | model_str = "LP1050 2Gb PCI-X"; | 871 | m = (typeof(m)){"LP1050", max_speed, ports, "PCI-X"}; |
815 | break; | 872 | break; |
816 | case PCI_DEVICE_ID_HELIOS: | 873 | case PCI_DEVICE_ID_HELIOS: |
817 | if (hdrtype == 0x80) | 874 | if (hdrtype == 0x80) |
818 | model_str = "LP11002 4Gb 2-port PCI-X2"; | 875 | m = (typeof(m)){"LP11002", max_speed, ports, "PCI-X2"}; |
819 | else | 876 | else |
820 | model_str = "LP11000 4Gb PCI-X2"; | 877 | m = (typeof(m)){"LP11000", max_speed, ports, "PCI-X2"}; |
821 | break; | 878 | break; |
822 | case PCI_DEVICE_ID_HELIOS_SCSP: | 879 | case PCI_DEVICE_ID_HELIOS_SCSP: |
823 | model_str = "LP11000-SP 4Gb PCI-X2"; | 880 | m = (typeof(m)){"LP11000-SP", max_speed, ports, "PCI-X2"}; |
824 | break; | 881 | break; |
825 | case PCI_DEVICE_ID_HELIOS_DCSP: | 882 | case PCI_DEVICE_ID_HELIOS_DCSP: |
826 | model_str = "LP11002-SP 4Gb 2-port PCI-X2"; | 883 | m = (typeof(m)){"LP11002-SP", max_speed, ports, "PCI-X2"}; |
827 | break; | 884 | break; |
828 | case PCI_DEVICE_ID_NEPTUNE: | 885 | case PCI_DEVICE_ID_NEPTUNE: |
829 | if (hdrtype == 0x80) | 886 | if (hdrtype == 0x80) |
830 | model_str = "LPe1002 4Gb 2-port"; | 887 | m = (typeof(m)){"LPe1002", max_speed, ports, "PCIe"}; |
831 | else | 888 | else |
832 | model_str = "LPe1000 4Gb PCIe"; | 889 | m = (typeof(m)){"LPe1000", max_speed, ports, "PCIe"}; |
833 | break; | 890 | break; |
834 | case PCI_DEVICE_ID_NEPTUNE_SCSP: | 891 | case PCI_DEVICE_ID_NEPTUNE_SCSP: |
835 | model_str = "LPe1000-SP 4Gb PCIe"; | 892 | m = (typeof(m)){"LPe1000-SP", max_speed, ports, "PCIe"}; |
836 | break; | 893 | break; |
837 | case PCI_DEVICE_ID_NEPTUNE_DCSP: | 894 | case PCI_DEVICE_ID_NEPTUNE_DCSP: |
838 | model_str = "LPe1002-SP 4Gb 2-port PCIe"; | 895 | m = (typeof(m)){"LPe1002-SP", max_speed, ports, "PCIe"}; |
839 | break; | 896 | break; |
840 | case PCI_DEVICE_ID_BMID: | 897 | case PCI_DEVICE_ID_BMID: |
841 | model_str = "LP1150 4Gb PCI-X2"; | 898 | m = (typeof(m)){"LP1150", max_speed, ports, "PCI-X2"}; |
842 | break; | 899 | break; |
843 | case PCI_DEVICE_ID_BSMB: | 900 | case PCI_DEVICE_ID_BSMB: |
844 | model_str = "LP111 4Gb PCI-X2"; | 901 | m = (typeof(m)){"LP111", max_speed, ports, "PCI-X2"}; |
845 | break; | 902 | break; |
846 | case PCI_DEVICE_ID_ZEPHYR: | 903 | case PCI_DEVICE_ID_ZEPHYR: |
847 | if (hdrtype == 0x80) | 904 | if (hdrtype == 0x80) |
848 | model_str = "LPe11002 4Gb 2-port PCIe"; | 905 | m = (typeof(m)){"LPe11002", max_speed, ports, "PCIe"}; |
849 | else | 906 | else |
850 | model_str = "LPe11000 4Gb PCIe"; | 907 | m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"}; |
851 | break; | 908 | break; |
852 | case PCI_DEVICE_ID_ZEPHYR_SCSP: | 909 | case PCI_DEVICE_ID_ZEPHYR_SCSP: |
853 | model_str = "LPe11000-SP 4Gb PCIe"; | 910 | m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"}; |
854 | break; | 911 | break; |
855 | case PCI_DEVICE_ID_ZEPHYR_DCSP: | 912 | case PCI_DEVICE_ID_ZEPHYR_DCSP: |
856 | model_str = "LPe11002-SP 4Gb 2-port PCIe"; | 913 | m = (typeof(m)){"LPe11002-SP", max_speed, ports, "PCIe"}; |
857 | break; | 914 | break; |
858 | case PCI_DEVICE_ID_ZMID: | 915 | case PCI_DEVICE_ID_ZMID: |
859 | model_str = "LPe1150 4Gb PCIe"; | 916 | m = (typeof(m)){"LPe1150", max_speed, ports, "PCIe"}; |
860 | break; | 917 | break; |
861 | case PCI_DEVICE_ID_ZSMB: | 918 | case PCI_DEVICE_ID_ZSMB: |
862 | model_str = "LPe111 4Gb PCIe"; | 919 | m = (typeof(m)){"LPe111", max_speed, ports, "PCIe"}; |
863 | break; | 920 | break; |
864 | case PCI_DEVICE_ID_LP101: | 921 | case PCI_DEVICE_ID_LP101: |
865 | model_str = "LP101 2Gb PCI-X"; | 922 | m = (typeof(m)){"LP101", max_speed, ports, "PCI-X"}; |
866 | break; | 923 | break; |
867 | case PCI_DEVICE_ID_LP10000S: | 924 | case PCI_DEVICE_ID_LP10000S: |
868 | model_str = "LP10000-S 2Gb PCI"; | 925 | m = (typeof(m)){"LP10000-S", max_speed, ports, "PCI"}; |
869 | break; | 926 | break; |
870 | case PCI_DEVICE_ID_LP11000S: | 927 | case PCI_DEVICE_ID_LP11000S: |
871 | case PCI_DEVICE_ID_LPE11000S: | 928 | case PCI_DEVICE_ID_LPE11000S: |
872 | switch (dev_subid) { | 929 | switch (dev_subid) { |
873 | case PCI_SUBSYSTEM_ID_LP11000S: | 930 | case PCI_SUBSYSTEM_ID_LP11000S: |
874 | model_str = "LP11002-S 4Gb PCI-X2"; | 931 | m = (typeof(m)){"LP11000-S", max_speed, |
932 | ports, "PCI-X2"}; | ||
875 | break; | 933 | break; |
876 | case PCI_SUBSYSTEM_ID_LP11002S: | 934 | case PCI_SUBSYSTEM_ID_LP11002S: |
877 | model_str = "LP11000-S 4Gb 2-port PCI-X2"; | 935 | m = (typeof(m)){"LP11002-S", max_speed, |
936 | ports, "PCI-X2"}; | ||
878 | break; | 937 | break; |
879 | case PCI_SUBSYSTEM_ID_LPE11000S: | 938 | case PCI_SUBSYSTEM_ID_LPE11000S: |
880 | model_str = "LPe11002-S 4Gb PCIe"; | 939 | m = (typeof(m)){"LPe11000-S", max_speed, |
940 | ports, "PCIe"}; | ||
881 | break; | 941 | break; |
882 | case PCI_SUBSYSTEM_ID_LPE11002S: | 942 | case PCI_SUBSYSTEM_ID_LPE11002S: |
883 | model_str = "LPe11002-S 4Gb 2-port PCIe"; | 943 | m = (typeof(m)){"LPe11002-S", max_speed, |
944 | ports, "PCIe"}; | ||
884 | break; | 945 | break; |
885 | case PCI_SUBSYSTEM_ID_LPE11010S: | 946 | case PCI_SUBSYSTEM_ID_LPE11010S: |
886 | model_str = "LPe11010-S 4Gb 10-port PCIe"; | 947 | m = (typeof(m)){"LPe11010-S", max_speed, |
948 | "10-port ", "PCIe"}; | ||
887 | break; | 949 | break; |
888 | default: | 950 | default: |
951 | m = (typeof(m)){ 0 }; | ||
889 | break; | 952 | break; |
890 | } | 953 | } |
891 | break; | 954 | break; |
892 | default: | 955 | default: |
956 | m = (typeof(m)){ 0 }; | ||
893 | break; | 957 | break; |
894 | } | 958 | } |
895 | if (mdp) | 959 | |
896 | sscanf(model_str, "%s", mdp); | 960 | if (mdp && mdp[0] == '\0') |
897 | if (descp) | 961 | snprintf(mdp, 79,"%s", m.name); |
898 | sprintf(descp, "Emulex %s Fibre Channel Adapter", model_str); | 962 | if (descp && descp[0] == '\0') |
963 | snprintf(descp, 255, | ||
964 | "Emulex %s %dGb %s%s Fibre Channel Adapter", | ||
965 | m.name, m.max_speed, m.ports, m.bus); | ||
899 | } | 966 | } |
900 | 967 | ||
901 | /**************************************************/ | 968 | /**************************************************/ |
@@ -1462,9 +1529,23 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1462 | phba->pci_bar2_map = pci_resource_start(phba->pcidev, 2); | 1529 | phba->pci_bar2_map = pci_resource_start(phba->pcidev, 2); |
1463 | bar2map_len = pci_resource_len(phba->pcidev, 2); | 1530 | bar2map_len = pci_resource_len(phba->pcidev, 2); |
1464 | 1531 | ||
1465 | /* Map HBA SLIM and Control Registers to a kernel virtual address. */ | 1532 | /* Map HBA SLIM to a kernel virtual address. */ |
1466 | phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len); | 1533 | phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len); |
1534 | if (!phba->slim_memmap_p) { | ||
1535 | error = -ENODEV; | ||
1536 | dev_printk(KERN_ERR, &pdev->dev, | ||
1537 | "ioremap failed for SLIM memory.\n"); | ||
1538 | goto out_idr_remove; | ||
1539 | } | ||
1540 | |||
1541 | /* Map HBA Control Registers to a kernel virtual address. */ | ||
1467 | phba->ctrl_regs_memmap_p = ioremap(phba->pci_bar2_map, bar2map_len); | 1542 | phba->ctrl_regs_memmap_p = ioremap(phba->pci_bar2_map, bar2map_len); |
1543 | if (!phba->ctrl_regs_memmap_p) { | ||
1544 | error = -ENODEV; | ||
1545 | dev_printk(KERN_ERR, &pdev->dev, | ||
1546 | "ioremap failed for HBA control registers.\n"); | ||
1547 | goto out_iounmap_slim; | ||
1548 | } | ||
1468 | 1549 | ||
1469 | /* Allocate memory for SLI-2 structures */ | 1550 | /* Allocate memory for SLI-2 structures */ |
1470 | phba->slim2p = dma_alloc_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE, | 1551 | phba->slim2p = dma_alloc_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE, |
@@ -1539,7 +1620,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1539 | INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list); | 1620 | INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list); |
1540 | 1621 | ||
1541 | host->transportt = lpfc_transport_template; | 1622 | host->transportt = lpfc_transport_template; |
1542 | host->hostdata[0] = (unsigned long)phba; | ||
1543 | pci_set_drvdata(pdev, host); | 1623 | pci_set_drvdata(pdev, host); |
1544 | error = scsi_add_host(host, &pdev->dev); | 1624 | error = scsi_add_host(host, &pdev->dev); |
1545 | if (error) | 1625 | if (error) |
@@ -1590,21 +1670,14 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1590 | lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(host)); | 1670 | lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(host)); |
1591 | 1671 | ||
1592 | fc_host_supported_speeds(host) = 0; | 1672 | fc_host_supported_speeds(host) = 0; |
1593 | switch (FC_JEDEC_ID(phba->vpd.rev.biuRev)) { | 1673 | if (phba->lmt & LMT_10Gb) |
1594 | case VIPER_JEDEC_ID: | ||
1595 | fc_host_supported_speeds(host) |= FC_PORTSPEED_10GBIT; | 1674 | fc_host_supported_speeds(host) |= FC_PORTSPEED_10GBIT; |
1596 | break; | 1675 | if (phba->lmt & LMT_4Gb) |
1597 | case HELIOS_JEDEC_ID: | ||
1598 | fc_host_supported_speeds(host) |= FC_PORTSPEED_4GBIT; | 1676 | fc_host_supported_speeds(host) |= FC_PORTSPEED_4GBIT; |
1599 | /* Fall through */ | 1677 | if (phba->lmt & LMT_2Gb) |
1600 | case CENTAUR_2G_JEDEC_ID: | ||
1601 | case PEGASUS_JEDEC_ID: | ||
1602 | case THOR_JEDEC_ID: | ||
1603 | fc_host_supported_speeds(host) |= FC_PORTSPEED_2GBIT; | 1678 | fc_host_supported_speeds(host) |= FC_PORTSPEED_2GBIT; |
1604 | /* Fall through */ | 1679 | if (phba->lmt & LMT_1Gb) |
1605 | default: | 1680 | fc_host_supported_speeds(host) |= FC_PORTSPEED_1GBIT; |
1606 | fc_host_supported_speeds(host) = FC_PORTSPEED_1GBIT; | ||
1607 | } | ||
1608 | 1681 | ||
1609 | fc_host_maxframe_size(host) = | 1682 | fc_host_maxframe_size(host) = |
1610 | ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) | | 1683 | ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) | |
@@ -1643,6 +1716,7 @@ out_free_slim: | |||
1643 | phba->slim2p_mapping); | 1716 | phba->slim2p_mapping); |
1644 | out_iounmap: | 1717 | out_iounmap: |
1645 | iounmap(phba->ctrl_regs_memmap_p); | 1718 | iounmap(phba->ctrl_regs_memmap_p); |
1719 | out_iounmap_slim: | ||
1646 | iounmap(phba->slim_memmap_p); | 1720 | iounmap(phba->slim_memmap_p); |
1647 | out_idr_remove: | 1721 | out_idr_remove: |
1648 | idr_remove(&lpfc_hba_index, phba->brd_no); | 1722 | idr_remove(&lpfc_hba_index, phba->brd_no); |
@@ -1660,7 +1734,7 @@ static void __devexit | |||
1660 | lpfc_pci_remove_one(struct pci_dev *pdev) | 1734 | lpfc_pci_remove_one(struct pci_dev *pdev) |
1661 | { | 1735 | { |
1662 | struct Scsi_Host *host = pci_get_drvdata(pdev); | 1736 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
1663 | struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata[0]; | 1737 | struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata; |
1664 | unsigned long iflag; | 1738 | unsigned long iflag; |
1665 | 1739 | ||
1666 | lpfc_free_sysfs_attr(phba); | 1740 | lpfc_free_sysfs_attr(phba); |
@@ -1681,6 +1755,7 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
1681 | * the HBA. | 1755 | * the HBA. |
1682 | */ | 1756 | */ |
1683 | lpfc_sli_hba_down(phba); | 1757 | lpfc_sli_hba_down(phba); |
1758 | lpfc_sli_brdrestart(phba); | ||
1684 | 1759 | ||
1685 | /* Release the irq reservation */ | 1760 | /* Release the irq reservation */ |
1686 | free_irq(phba->pcidev->irq, phba); | 1761 | free_irq(phba->pcidev->irq, phba); |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index e3bc8d3f7302..c585e2b2e589 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -195,6 +195,9 @@ lpfc_init_link(struct lpfc_hba * phba, | |||
195 | mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; | 195 | mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; |
196 | mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; | 196 | mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; |
197 | break; | 197 | break; |
198 | case FLAGS_LOCAL_LB: | ||
199 | mb->un.varInitLnk.link_flags = FLAGS_LOCAL_LB; | ||
200 | break; | ||
198 | } | 201 | } |
199 | 202 | ||
200 | /* NEW_FEATURE | 203 | /* NEW_FEATURE |
@@ -336,6 +339,23 @@ lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
336 | return; | 339 | return; |
337 | } | 340 | } |
338 | 341 | ||
342 | /*************************************************/ | ||
343 | /* lpfc_read_lnk_stat Issue a READ LINK STATUS */ | ||
344 | /* mailbox command */ | ||
345 | /*************************************************/ | ||
346 | void | ||
347 | lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | ||
348 | { | ||
349 | MAILBOX_t *mb; | ||
350 | |||
351 | mb = &pmb->mb; | ||
352 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | ||
353 | |||
354 | mb->mbxCommand = MBX_READ_LNK_STAT; | ||
355 | mb->mbxOwner = OWN_HOST; | ||
356 | return; | ||
357 | } | ||
358 | |||
339 | /********************************************/ | 359 | /********************************************/ |
340 | /* lpfc_reg_login Issue a REG_LOGIN */ | 360 | /* lpfc_reg_login Issue a REG_LOGIN */ |
341 | /* mailbox command */ | 361 | /* mailbox command */ |
@@ -620,6 +640,17 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
620 | } | 640 | } |
621 | 641 | ||
622 | void | 642 | void |
643 | lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | ||
644 | { | ||
645 | MAILBOX_t *mb = &pmb->mb; | ||
646 | |||
647 | memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); | ||
648 | mb->mbxCommand = MBX_KILL_BOARD; | ||
649 | mb->mbxOwner = OWN_HOST; | ||
650 | return; | ||
651 | } | ||
652 | |||
653 | void | ||
623 | lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) | 654 | lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) |
624 | { | 655 | { |
625 | struct lpfc_sli *psli; | 656 | struct lpfc_sli *psli; |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index fbead786031f..3d77bd999b70 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -46,13 +46,13 @@ lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
46 | * table entry for that node. | 46 | * table entry for that node. |
47 | */ | 47 | */ |
48 | if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0) | 48 | if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0) |
49 | return (0); | 49 | return 0; |
50 | 50 | ||
51 | if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0) | 51 | if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0) |
52 | return (0); | 52 | return 0; |
53 | 53 | ||
54 | /* we match, return success */ | 54 | /* we match, return success */ |
55 | return (1); | 55 | return 1; |
56 | } | 56 | } |
57 | 57 | ||
58 | int | 58 | int |
@@ -150,8 +150,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, | |||
150 | lp = (uint32_t *) prsp->virt; | 150 | lp = (uint32_t *) prsp->virt; |
151 | ptr = (void *)((uint8_t *)lp + sizeof(uint32_t)); | 151 | ptr = (void *)((uint8_t *)lp + sizeof(uint32_t)); |
152 | } | 152 | } |
153 | } | 153 | } else { |
154 | else { | ||
155 | /* Force ulpStatus error since we are returning NULL ptr */ | 154 | /* Force ulpStatus error since we are returning NULL ptr */ |
156 | if (!(irsp->ulpStatus)) { | 155 | if (!(irsp->ulpStatus)) { |
157 | irsp->ulpStatus = IOSTAT_LOCAL_REJECT; | 156 | irsp->ulpStatus = IOSTAT_LOCAL_REJECT; |
@@ -159,7 +158,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, | |||
159 | } | 158 | } |
160 | ptr = NULL; | 159 | ptr = NULL; |
161 | } | 160 | } |
162 | return (ptr); | 161 | return ptr; |
163 | } | 162 | } |
164 | 163 | ||
165 | 164 | ||
@@ -260,13 +259,9 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
260 | } while(found); | 259 | } while(found); |
261 | 260 | ||
262 | /* If we are delaying issuing an ELS command, cancel it */ | 261 | /* If we are delaying issuing an ELS command, cancel it */ |
263 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 262 | if (ndlp->nlp_flag & NLP_DELAY_TMO) |
264 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 263 | lpfc_cancel_retry_delay_tmo(phba, ndlp); |
265 | del_timer_sync(&ndlp->nlp_delayfunc); | 264 | return 0; |
266 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | ||
267 | list_del_init(&ndlp->els_retry_evt.evt_listp); | ||
268 | } | ||
269 | return (0); | ||
270 | } | 265 | } |
271 | 266 | ||
272 | static int | 267 | static int |
@@ -300,12 +295,10 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
300 | /* Start discovery - this should just do | 295 | /* Start discovery - this should just do |
301 | CLEAR_LA */ | 296 | CLEAR_LA */ |
302 | lpfc_disc_start(phba); | 297 | lpfc_disc_start(phba); |
303 | } | 298 | } else { |
304 | else { | ||
305 | lpfc_initial_flogi(phba); | 299 | lpfc_initial_flogi(phba); |
306 | } | 300 | } |
307 | } | 301 | } else { |
308 | else { | ||
309 | stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; | 302 | stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; |
310 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; | 303 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; |
311 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, | 304 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, |
@@ -321,7 +314,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
321 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 314 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
322 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; | 315 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; |
323 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 316 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
324 | return (0); | 317 | return 0; |
325 | } | 318 | } |
326 | icmd = &cmdiocb->iocb; | 319 | icmd = &cmdiocb->iocb; |
327 | 320 | ||
@@ -353,7 +346,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
353 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; | 346 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; |
354 | 347 | ||
355 | /* no need to reg_login if we are already in one of these states */ | 348 | /* no need to reg_login if we are already in one of these states */ |
356 | switch(ndlp->nlp_state) { | 349 | switch (ndlp->nlp_state) { |
357 | case NLP_STE_NPR_NODE: | 350 | case NLP_STE_NPR_NODE: |
358 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) | 351 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) |
359 | break; | 352 | break; |
@@ -362,7 +355,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
362 | case NLP_STE_UNMAPPED_NODE: | 355 | case NLP_STE_UNMAPPED_NODE: |
363 | case NLP_STE_MAPPED_NODE: | 356 | case NLP_STE_MAPPED_NODE: |
364 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); | 357 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); |
365 | return (1); | 358 | return 1; |
366 | } | 359 | } |
367 | 360 | ||
368 | if ((phba->fc_flag & FC_PT2PT) | 361 | if ((phba->fc_flag & FC_PT2PT) |
@@ -398,24 +391,16 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
398 | */ | 391 | */ |
399 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | 392 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
400 | mbox->context2 = ndlp; | 393 | mbox->context2 = ndlp; |
401 | ndlp->nlp_flag |= NLP_ACC_REGLOGIN; | 394 | ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); |
402 | 395 | ||
403 | /* If there is an outstanding PLOGI issued, abort it before | ||
404 | * sending ACC rsp to PLOGI recieved. | ||
405 | */ | ||
406 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) { | ||
407 | /* software abort outstanding PLOGI */ | ||
408 | lpfc_els_abort(phba, ndlp, 1); | ||
409 | } | ||
410 | ndlp->nlp_flag |= NLP_RCV_PLOGI; | ||
411 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); | 396 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); |
412 | return (1); | 397 | return 1; |
413 | 398 | ||
414 | out: | 399 | out: |
415 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 400 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
416 | stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; | 401 | stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; |
417 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 402 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
418 | return (0); | 403 | return 0; |
419 | } | 404 | } |
420 | 405 | ||
421 | static int | 406 | static int |
@@ -451,12 +436,11 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, | |||
451 | (lpfc_check_adisc(phba, ndlp, pnn, ppn))) { | 436 | (lpfc_check_adisc(phba, ndlp, pnn, ppn))) { |
452 | if (cmd == ELS_CMD_ADISC) { | 437 | if (cmd == ELS_CMD_ADISC) { |
453 | lpfc_els_rsp_adisc_acc(phba, cmdiocb, ndlp); | 438 | lpfc_els_rsp_adisc_acc(phba, cmdiocb, ndlp); |
454 | } | 439 | } else { |
455 | else { | ||
456 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, | 440 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, |
457 | NULL, 0); | 441 | NULL, 0); |
458 | } | 442 | } |
459 | return (1); | 443 | return 1; |
460 | } | 444 | } |
461 | /* Reject this request because invalid parameters */ | 445 | /* Reject this request because invalid parameters */ |
462 | stat.un.b.lsRjtRsvd0 = 0; | 446 | stat.un.b.lsRjtRsvd0 = 0; |
@@ -465,16 +449,17 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, | |||
465 | stat.un.b.vendorUnique = 0; | 449 | stat.un.b.vendorUnique = 0; |
466 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 450 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
467 | 451 | ||
468 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
469 | /* 1 sec timeout */ | 452 | /* 1 sec timeout */ |
470 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 453 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
471 | 454 | ||
472 | spin_lock_irq(phba->host->host_lock); | 455 | spin_lock_irq(phba->host->host_lock); |
473 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 456 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
474 | spin_unlock_irq(phba->host->host_lock); | 457 | spin_unlock_irq(phba->host->host_lock); |
458 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
459 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
475 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 460 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
476 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 461 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
477 | return (0); | 462 | return 0; |
478 | } | 463 | } |
479 | 464 | ||
480 | static int | 465 | static int |
@@ -489,25 +474,33 @@ lpfc_rcv_logo(struct lpfc_hba * phba, | |||
489 | ndlp->nlp_flag |= NLP_LOGO_ACC; | 474 | ndlp->nlp_flag |= NLP_LOGO_ACC; |
490 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 475 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
491 | 476 | ||
492 | if (!(ndlp->nlp_type & NLP_FABRIC)) { | 477 | if (!(ndlp->nlp_type & NLP_FABRIC) || |
478 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { | ||
493 | /* Only try to re-login if this is NOT a Fabric Node */ | 479 | /* Only try to re-login if this is NOT a Fabric Node */ |
494 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
495 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 480 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
496 | spin_lock_irq(phba->host->host_lock); | 481 | spin_lock_irq(phba->host->host_lock); |
497 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 482 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
498 | spin_unlock_irq(phba->host->host_lock); | 483 | spin_unlock_irq(phba->host->host_lock); |
499 | } | ||
500 | 484 | ||
501 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 485 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
502 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 486 | ndlp->nlp_prev_state = ndlp->nlp_state; |
487 | ndlp->nlp_state = NLP_STE_NPR_NODE; | ||
488 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | ||
489 | } else { | ||
490 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
491 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; | ||
492 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | ||
493 | } | ||
503 | 494 | ||
495 | spin_lock_irq(phba->host->host_lock); | ||
504 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 496 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
497 | spin_unlock_irq(phba->host->host_lock); | ||
505 | /* The driver has to wait until the ACC completes before it continues | 498 | /* The driver has to wait until the ACC completes before it continues |
506 | * processing the LOGO. The action will resume in | 499 | * processing the LOGO. The action will resume in |
507 | * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an | 500 | * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an |
508 | * unreg_login, the driver waits so the ACC does not get aborted. | 501 | * unreg_login, the driver waits so the ACC does not get aborted. |
509 | */ | 502 | */ |
510 | return (0); | 503 | return 0; |
511 | } | 504 | } |
512 | 505 | ||
513 | static void | 506 | static void |
@@ -555,20 +548,12 @@ lpfc_disc_set_adisc(struct lpfc_hba * phba, | |||
555 | if ((phba->cfg_use_adisc == 0) && | 548 | if ((phba->cfg_use_adisc == 0) && |
556 | !(phba->fc_flag & FC_RSCN_MODE)) { | 549 | !(phba->fc_flag & FC_RSCN_MODE)) { |
557 | if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) | 550 | if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) |
558 | return (0); | 551 | return 0; |
559 | } | 552 | } |
560 | spin_lock_irq(phba->host->host_lock); | 553 | spin_lock_irq(phba->host->host_lock); |
561 | ndlp->nlp_flag |= NLP_NPR_ADISC; | 554 | ndlp->nlp_flag |= NLP_NPR_ADISC; |
562 | spin_unlock_irq(phba->host->host_lock); | 555 | spin_unlock_irq(phba->host->host_lock); |
563 | return (1); | 556 | return 1; |
564 | } | ||
565 | |||
566 | static uint32_t | ||
567 | lpfc_disc_noop(struct lpfc_hba * phba, | ||
568 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | ||
569 | { | ||
570 | /* This routine does nothing, just return the current state */ | ||
571 | return (ndlp->nlp_state); | ||
572 | } | 557 | } |
573 | 558 | ||
574 | static uint32_t | 559 | static uint32_t |
@@ -583,7 +568,7 @@ lpfc_disc_illegal(struct lpfc_hba * phba, | |||
583 | phba->brd_no, | 568 | phba->brd_no, |
584 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, | 569 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, |
585 | ndlp->nlp_flag); | 570 | ndlp->nlp_flag); |
586 | return (ndlp->nlp_state); | 571 | return ndlp->nlp_state; |
587 | } | 572 | } |
588 | 573 | ||
589 | /* Start of Discovery State Machine routines */ | 574 | /* Start of Discovery State Machine routines */ |
@@ -597,12 +582,13 @@ lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba, | |||
597 | cmdiocb = (struct lpfc_iocbq *) arg; | 582 | cmdiocb = (struct lpfc_iocbq *) arg; |
598 | 583 | ||
599 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 584 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { |
585 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | ||
600 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; | 586 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; |
601 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | 587 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); |
602 | return (ndlp->nlp_state); | 588 | return ndlp->nlp_state; |
603 | } | 589 | } |
604 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 590 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
605 | return (NLP_STE_FREED_NODE); | 591 | return NLP_STE_FREED_NODE; |
606 | } | 592 | } |
607 | 593 | ||
608 | static uint32_t | 594 | static uint32_t |
@@ -611,7 +597,7 @@ lpfc_rcv_els_unused_node(struct lpfc_hba * phba, | |||
611 | { | 597 | { |
612 | lpfc_issue_els_logo(phba, ndlp, 0); | 598 | lpfc_issue_els_logo(phba, ndlp, 0); |
613 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | 599 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); |
614 | return (ndlp->nlp_state); | 600 | return ndlp->nlp_state; |
615 | } | 601 | } |
616 | 602 | ||
617 | static uint32_t | 603 | static uint32_t |
@@ -628,7 +614,7 @@ lpfc_rcv_logo_unused_node(struct lpfc_hba * phba, | |||
628 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 614 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
629 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | 615 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); |
630 | 616 | ||
631 | return (ndlp->nlp_state); | 617 | return ndlp->nlp_state; |
632 | } | 618 | } |
633 | 619 | ||
634 | static uint32_t | 620 | static uint32_t |
@@ -636,7 +622,7 @@ lpfc_cmpl_logo_unused_node(struct lpfc_hba * phba, | |||
636 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 622 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
637 | { | 623 | { |
638 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 624 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
639 | return (NLP_STE_FREED_NODE); | 625 | return NLP_STE_FREED_NODE; |
640 | } | 626 | } |
641 | 627 | ||
642 | static uint32_t | 628 | static uint32_t |
@@ -644,7 +630,7 @@ lpfc_device_rm_unused_node(struct lpfc_hba * phba, | |||
644 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 630 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
645 | { | 631 | { |
646 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 632 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
647 | return (NLP_STE_FREED_NODE); | 633 | return NLP_STE_FREED_NODE; |
648 | } | 634 | } |
649 | 635 | ||
650 | static uint32_t | 636 | static uint32_t |
@@ -677,12 +663,26 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
677 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 663 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
678 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; | 664 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; |
679 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 665 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
680 | } | 666 | } else { |
681 | else { | ||
682 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 667 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); |
683 | } /* if our portname was less */ | 668 | } /* if our portname was less */ |
684 | 669 | ||
685 | return (ndlp->nlp_state); | 670 | return ndlp->nlp_state; |
671 | } | ||
672 | |||
673 | static uint32_t | ||
674 | lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba, | ||
675 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | ||
676 | { | ||
677 | struct lpfc_iocbq *cmdiocb; | ||
678 | |||
679 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
680 | |||
681 | /* software abort outstanding PLOGI */ | ||
682 | lpfc_els_abort(phba, ndlp, 1); | ||
683 | |||
684 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | ||
685 | return ndlp->nlp_state; | ||
686 | } | 686 | } |
687 | 687 | ||
688 | static uint32_t | 688 | static uint32_t |
@@ -695,24 +695,24 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, | |||
695 | 695 | ||
696 | /* software abort outstanding PLOGI */ | 696 | /* software abort outstanding PLOGI */ |
697 | lpfc_els_abort(phba, ndlp, 1); | 697 | lpfc_els_abort(phba, ndlp, 1); |
698 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | ||
699 | spin_lock_irq(phba->host->host_lock); | ||
700 | ndlp->nlp_flag |= NLP_DELAY_TMO; | ||
701 | spin_unlock_irq(phba->host->host_lock); | ||
702 | 698 | ||
703 | if (evt == NLP_EVT_RCV_LOGO) { | 699 | if (evt == NLP_EVT_RCV_LOGO) { |
704 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 700 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
705 | } | 701 | } else { |
706 | else { | ||
707 | lpfc_issue_els_logo(phba, ndlp, 0); | 702 | lpfc_issue_els_logo(phba, ndlp, 0); |
708 | } | 703 | } |
709 | 704 | ||
710 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 705 | /* Put ndlp in npr list set plogi timer for 1 sec */ |
711 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | 706 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
707 | spin_lock_irq(phba->host->host_lock); | ||
708 | ndlp->nlp_flag |= NLP_DELAY_TMO; | ||
709 | spin_unlock_irq(phba->host->host_lock); | ||
710 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
711 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; | ||
712 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 712 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
713 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 713 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
714 | 714 | ||
715 | return (ndlp->nlp_state); | 715 | return ndlp->nlp_state; |
716 | } | 716 | } |
717 | 717 | ||
718 | static uint32_t | 718 | static uint32_t |
@@ -731,7 +731,8 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
731 | rspiocb = cmdiocb->context_un.rsp_iocb; | 731 | rspiocb = cmdiocb->context_un.rsp_iocb; |
732 | 732 | ||
733 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | 733 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { |
734 | return (ndlp->nlp_state); | 734 | /* Recovery from PLOGI collision logic */ |
735 | return ndlp->nlp_state; | ||
735 | } | 736 | } |
736 | 737 | ||
737 | irsp = &rspiocb->iocb; | 738 | irsp = &rspiocb->iocb; |
@@ -791,7 +792,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
791 | * execute first, queue this command to | 792 | * execute first, queue this command to |
792 | * be processed later. | 793 | * be processed later. |
793 | */ | 794 | */ |
794 | switch(ndlp->nlp_DID) { | 795 | switch (ndlp->nlp_DID) { |
795 | case NameServer_DID: | 796 | case NameServer_DID: |
796 | mbox->mbox_cmpl = | 797 | mbox->mbox_cmpl = |
797 | lpfc_mbx_cmpl_ns_reg_login; | 798 | lpfc_mbx_cmpl_ns_reg_login; |
@@ -812,7 +813,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
812 | NLP_STE_REG_LOGIN_ISSUE; | 813 | NLP_STE_REG_LOGIN_ISSUE; |
813 | lpfc_nlp_list(phba, ndlp, | 814 | lpfc_nlp_list(phba, ndlp, |
814 | NLP_REGLOGIN_LIST); | 815 | NLP_REGLOGIN_LIST); |
815 | return (ndlp->nlp_state); | 816 | return ndlp->nlp_state; |
816 | } | 817 | } |
817 | mempool_free(mbox, phba->mbox_mem_pool); | 818 | mempool_free(mbox, phba->mbox_mem_pool); |
818 | } else { | 819 | } else { |
@@ -824,7 +825,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
824 | /* Free this node since the driver cannot login or has the wrong | 825 | /* Free this node since the driver cannot login or has the wrong |
825 | sparm */ | 826 | sparm */ |
826 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 827 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
827 | return (NLP_STE_FREED_NODE); | 828 | return NLP_STE_FREED_NODE; |
828 | } | 829 | } |
829 | 830 | ||
830 | static uint32_t | 831 | static uint32_t |
@@ -835,7 +836,7 @@ lpfc_device_rm_plogi_issue(struct lpfc_hba * phba, | |||
835 | lpfc_els_abort(phba, ndlp, 1); | 836 | lpfc_els_abort(phba, ndlp, 1); |
836 | 837 | ||
837 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 838 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
838 | return (NLP_STE_FREED_NODE); | 839 | return NLP_STE_FREED_NODE; |
839 | } | 840 | } |
840 | 841 | ||
841 | static uint32_t | 842 | static uint32_t |
@@ -846,13 +847,14 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, | |||
846 | /* software abort outstanding PLOGI */ | 847 | /* software abort outstanding PLOGI */ |
847 | lpfc_els_abort(phba, ndlp, 1); | 848 | lpfc_els_abort(phba, ndlp, 1); |
848 | 849 | ||
850 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; | ||
849 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 851 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
850 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 852 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
851 | spin_lock_irq(phba->host->host_lock); | 853 | spin_lock_irq(phba->host->host_lock); |
852 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 854 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
853 | spin_unlock_irq(phba->host->host_lock); | 855 | spin_unlock_irq(phba->host->host_lock); |
854 | 856 | ||
855 | return (ndlp->nlp_state); | 857 | return ndlp->nlp_state; |
856 | } | 858 | } |
857 | 859 | ||
858 | static uint32_t | 860 | static uint32_t |
@@ -868,13 +870,14 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, | |||
868 | cmdiocb = (struct lpfc_iocbq *) arg; | 870 | cmdiocb = (struct lpfc_iocbq *) arg; |
869 | 871 | ||
870 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 872 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { |
871 | return (ndlp->nlp_state); | 873 | return ndlp->nlp_state; |
872 | } | 874 | } |
875 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
873 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 876 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
874 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 877 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
875 | lpfc_issue_els_plogi(phba, ndlp, 0); | 878 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
876 | 879 | ||
877 | return (ndlp->nlp_state); | 880 | return ndlp->nlp_state; |
878 | } | 881 | } |
879 | 882 | ||
880 | static uint32_t | 883 | static uint32_t |
@@ -887,7 +890,7 @@ lpfc_rcv_prli_adisc_issue(struct lpfc_hba * phba, | |||
887 | cmdiocb = (struct lpfc_iocbq *) arg; | 890 | cmdiocb = (struct lpfc_iocbq *) arg; |
888 | 891 | ||
889 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 892 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); |
890 | return (ndlp->nlp_state); | 893 | return ndlp->nlp_state; |
891 | } | 894 | } |
892 | 895 | ||
893 | static uint32_t | 896 | static uint32_t |
@@ -903,7 +906,7 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, | |||
903 | lpfc_els_abort(phba, ndlp, 0); | 906 | lpfc_els_abort(phba, ndlp, 0); |
904 | 907 | ||
905 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 908 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
906 | return (ndlp->nlp_state); | 909 | return ndlp->nlp_state; |
907 | } | 910 | } |
908 | 911 | ||
909 | static uint32_t | 912 | static uint32_t |
@@ -916,7 +919,7 @@ lpfc_rcv_padisc_adisc_issue(struct lpfc_hba * phba, | |||
916 | cmdiocb = (struct lpfc_iocbq *) arg; | 919 | cmdiocb = (struct lpfc_iocbq *) arg; |
917 | 920 | ||
918 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 921 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
919 | return (ndlp->nlp_state); | 922 | return ndlp->nlp_state; |
920 | } | 923 | } |
921 | 924 | ||
922 | static uint32_t | 925 | static uint32_t |
@@ -930,7 +933,7 @@ lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba, | |||
930 | 933 | ||
931 | /* Treat like rcv logo */ | 934 | /* Treat like rcv logo */ |
932 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 935 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
933 | return (ndlp->nlp_state); | 936 | return ndlp->nlp_state; |
934 | } | 937 | } |
935 | 938 | ||
936 | static uint32_t | 939 | static uint32_t |
@@ -950,29 +953,33 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, | |||
950 | 953 | ||
951 | if ((irsp->ulpStatus) || | 954 | if ((irsp->ulpStatus) || |
952 | (!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) { | 955 | (!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) { |
953 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
954 | /* 1 sec timeout */ | 956 | /* 1 sec timeout */ |
955 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 957 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
956 | spin_lock_irq(phba->host->host_lock); | 958 | spin_lock_irq(phba->host->host_lock); |
957 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 959 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
958 | spin_unlock_irq(phba->host->host_lock); | 960 | spin_unlock_irq(phba->host->host_lock); |
961 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
959 | 962 | ||
960 | memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name)); | 963 | memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name)); |
961 | memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); | 964 | memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); |
962 | 965 | ||
966 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
963 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 967 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
964 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 968 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
965 | lpfc_unreg_rpi(phba, ndlp); | 969 | lpfc_unreg_rpi(phba, ndlp); |
966 | return (ndlp->nlp_state); | 970 | return ndlp->nlp_state; |
967 | } | 971 | } |
972 | |||
968 | if (ndlp->nlp_type & NLP_FCP_TARGET) { | 973 | if (ndlp->nlp_type & NLP_FCP_TARGET) { |
974 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
969 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; | 975 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; |
970 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); | 976 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); |
971 | } else { | 977 | } else { |
978 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
972 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | 979 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; |
973 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | 980 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); |
974 | } | 981 | } |
975 | return (ndlp->nlp_state); | 982 | return ndlp->nlp_state; |
976 | } | 983 | } |
977 | 984 | ||
978 | static uint32_t | 985 | static uint32_t |
@@ -984,7 +991,7 @@ lpfc_device_rm_adisc_issue(struct lpfc_hba * phba, | |||
984 | lpfc_els_abort(phba, ndlp, 1); | 991 | lpfc_els_abort(phba, ndlp, 1); |
985 | 992 | ||
986 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 993 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
987 | return (NLP_STE_FREED_NODE); | 994 | return NLP_STE_FREED_NODE; |
988 | } | 995 | } |
989 | 996 | ||
990 | static uint32_t | 997 | static uint32_t |
@@ -995,14 +1002,15 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, | |||
995 | /* software abort outstanding ADISC */ | 1002 | /* software abort outstanding ADISC */ |
996 | lpfc_els_abort(phba, ndlp, 1); | 1003 | lpfc_els_abort(phba, ndlp, 1); |
997 | 1004 | ||
1005 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
998 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1006 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
999 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1007 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1000 | spin_lock_irq(phba->host->host_lock); | 1008 | spin_lock_irq(phba->host->host_lock); |
1001 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1009 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1010 | ndlp->nlp_flag |= NLP_NPR_ADISC; | ||
1002 | spin_unlock_irq(phba->host->host_lock); | 1011 | spin_unlock_irq(phba->host->host_lock); |
1003 | 1012 | ||
1004 | lpfc_disc_set_adisc(phba, ndlp); | 1013 | return ndlp->nlp_state; |
1005 | return (ndlp->nlp_state); | ||
1006 | } | 1014 | } |
1007 | 1015 | ||
1008 | static uint32_t | 1016 | static uint32_t |
@@ -1015,7 +1023,7 @@ lpfc_rcv_plogi_reglogin_issue(struct lpfc_hba * phba, | |||
1015 | cmdiocb = (struct lpfc_iocbq *) arg; | 1023 | cmdiocb = (struct lpfc_iocbq *) arg; |
1016 | 1024 | ||
1017 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1025 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); |
1018 | return (ndlp->nlp_state); | 1026 | return ndlp->nlp_state; |
1019 | } | 1027 | } |
1020 | 1028 | ||
1021 | static uint32_t | 1029 | static uint32_t |
@@ -1028,7 +1036,7 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_hba * phba, | |||
1028 | cmdiocb = (struct lpfc_iocbq *) arg; | 1036 | cmdiocb = (struct lpfc_iocbq *) arg; |
1029 | 1037 | ||
1030 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1038 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); |
1031 | return (ndlp->nlp_state); | 1039 | return ndlp->nlp_state; |
1032 | } | 1040 | } |
1033 | 1041 | ||
1034 | static uint32_t | 1042 | static uint32_t |
@@ -1041,7 +1049,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, | |||
1041 | cmdiocb = (struct lpfc_iocbq *) arg; | 1049 | cmdiocb = (struct lpfc_iocbq *) arg; |
1042 | 1050 | ||
1043 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1051 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1044 | return (ndlp->nlp_state); | 1052 | return ndlp->nlp_state; |
1045 | } | 1053 | } |
1046 | 1054 | ||
1047 | static uint32_t | 1055 | static uint32_t |
@@ -1054,7 +1062,7 @@ lpfc_rcv_padisc_reglogin_issue(struct lpfc_hba * phba, | |||
1054 | cmdiocb = (struct lpfc_iocbq *) arg; | 1062 | cmdiocb = (struct lpfc_iocbq *) arg; |
1055 | 1063 | ||
1056 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1064 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
1057 | return (ndlp->nlp_state); | 1065 | return ndlp->nlp_state; |
1058 | } | 1066 | } |
1059 | 1067 | ||
1060 | static uint32_t | 1068 | static uint32_t |
@@ -1066,7 +1074,7 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba, | |||
1066 | 1074 | ||
1067 | cmdiocb = (struct lpfc_iocbq *) arg; | 1075 | cmdiocb = (struct lpfc_iocbq *) arg; |
1068 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1076 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
1069 | return (ndlp->nlp_state); | 1077 | return ndlp->nlp_state; |
1070 | } | 1078 | } |
1071 | 1079 | ||
1072 | static uint32_t | 1080 | static uint32_t |
@@ -1090,31 +1098,34 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1090 | phba->brd_no, | 1098 | phba->brd_no, |
1091 | did, mb->mbxStatus, phba->hba_state); | 1099 | did, mb->mbxStatus, phba->hba_state); |
1092 | 1100 | ||
1101 | /* Put ndlp in npr list set plogi timer for 1 sec */ | ||
1093 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 1102 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
1094 | spin_lock_irq(phba->host->host_lock); | 1103 | spin_lock_irq(phba->host->host_lock); |
1095 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1104 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1096 | spin_unlock_irq(phba->host->host_lock); | 1105 | spin_unlock_irq(phba->host->host_lock); |
1106 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
1097 | 1107 | ||
1098 | lpfc_issue_els_logo(phba, ndlp, 0); | 1108 | lpfc_issue_els_logo(phba, ndlp, 0); |
1099 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 1109 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1100 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
1101 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1110 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1102 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1111 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1103 | return (ndlp->nlp_state); | 1112 | return ndlp->nlp_state; |
1104 | } | 1113 | } |
1105 | 1114 | ||
1106 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1115 | ndlp->nlp_rpi = mb->un.varWords[0]; |
1107 | 1116 | ||
1108 | /* Only if we are not a fabric nport do we issue PRLI */ | 1117 | /* Only if we are not a fabric nport do we issue PRLI */ |
1109 | if (!(ndlp->nlp_type & NLP_FABRIC)) { | 1118 | if (!(ndlp->nlp_type & NLP_FABRIC)) { |
1119 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
1110 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; | 1120 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; |
1111 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); | 1121 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); |
1112 | lpfc_issue_els_prli(phba, ndlp, 0); | 1122 | lpfc_issue_els_prli(phba, ndlp, 0); |
1113 | } else { | 1123 | } else { |
1124 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
1114 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | 1125 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; |
1115 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | 1126 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); |
1116 | } | 1127 | } |
1117 | return (ndlp->nlp_state); | 1128 | return ndlp->nlp_state; |
1118 | } | 1129 | } |
1119 | 1130 | ||
1120 | static uint32_t | 1131 | static uint32_t |
@@ -1123,7 +1134,7 @@ lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba, | |||
1123 | uint32_t evt) | 1134 | uint32_t evt) |
1124 | { | 1135 | { |
1125 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1136 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
1126 | return (NLP_STE_FREED_NODE); | 1137 | return NLP_STE_FREED_NODE; |
1127 | } | 1138 | } |
1128 | 1139 | ||
1129 | static uint32_t | 1140 | static uint32_t |
@@ -1131,12 +1142,13 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, | |||
1131 | struct lpfc_nodelist * ndlp, void *arg, | 1142 | struct lpfc_nodelist * ndlp, void *arg, |
1132 | uint32_t evt) | 1143 | uint32_t evt) |
1133 | { | 1144 | { |
1145 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
1134 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1146 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1135 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1147 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1136 | spin_lock_irq(phba->host->host_lock); | 1148 | spin_lock_irq(phba->host->host_lock); |
1137 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1149 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1138 | spin_unlock_irq(phba->host->host_lock); | 1150 | spin_unlock_irq(phba->host->host_lock); |
1139 | return (ndlp->nlp_state); | 1151 | return ndlp->nlp_state; |
1140 | } | 1152 | } |
1141 | 1153 | ||
1142 | static uint32_t | 1154 | static uint32_t |
@@ -1148,7 +1160,7 @@ lpfc_rcv_plogi_prli_issue(struct lpfc_hba * phba, | |||
1148 | cmdiocb = (struct lpfc_iocbq *) arg; | 1160 | cmdiocb = (struct lpfc_iocbq *) arg; |
1149 | 1161 | ||
1150 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1162 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); |
1151 | return (ndlp->nlp_state); | 1163 | return ndlp->nlp_state; |
1152 | } | 1164 | } |
1153 | 1165 | ||
1154 | static uint32_t | 1166 | static uint32_t |
@@ -1160,7 +1172,7 @@ lpfc_rcv_prli_prli_issue(struct lpfc_hba * phba, | |||
1160 | cmdiocb = (struct lpfc_iocbq *) arg; | 1172 | cmdiocb = (struct lpfc_iocbq *) arg; |
1161 | 1173 | ||
1162 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1174 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); |
1163 | return (ndlp->nlp_state); | 1175 | return ndlp->nlp_state; |
1164 | } | 1176 | } |
1165 | 1177 | ||
1166 | static uint32_t | 1178 | static uint32_t |
@@ -1175,7 +1187,7 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba, | |||
1175 | lpfc_els_abort(phba, ndlp, 1); | 1187 | lpfc_els_abort(phba, ndlp, 1); |
1176 | 1188 | ||
1177 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1189 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1178 | return (ndlp->nlp_state); | 1190 | return ndlp->nlp_state; |
1179 | } | 1191 | } |
1180 | 1192 | ||
1181 | static uint32_t | 1193 | static uint32_t |
@@ -1187,7 +1199,7 @@ lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba, | |||
1187 | cmdiocb = (struct lpfc_iocbq *) arg; | 1199 | cmdiocb = (struct lpfc_iocbq *) arg; |
1188 | 1200 | ||
1189 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1201 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
1190 | return (ndlp->nlp_state); | 1202 | return ndlp->nlp_state; |
1191 | } | 1203 | } |
1192 | 1204 | ||
1193 | /* This routine is envoked when we rcv a PRLO request from a nport | 1205 | /* This routine is envoked when we rcv a PRLO request from a nport |
@@ -1203,7 +1215,7 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba, | |||
1203 | 1215 | ||
1204 | cmdiocb = (struct lpfc_iocbq *) arg; | 1216 | cmdiocb = (struct lpfc_iocbq *) arg; |
1205 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1217 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
1206 | return (ndlp->nlp_state); | 1218 | return ndlp->nlp_state; |
1207 | } | 1219 | } |
1208 | 1220 | ||
1209 | static uint32_t | 1221 | static uint32_t |
@@ -1220,9 +1232,10 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1220 | 1232 | ||
1221 | irsp = &rspiocb->iocb; | 1233 | irsp = &rspiocb->iocb; |
1222 | if (irsp->ulpStatus) { | 1234 | if (irsp->ulpStatus) { |
1235 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | ||
1223 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | 1236 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; |
1224 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | 1237 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); |
1225 | return (ndlp->nlp_state); | 1238 | return ndlp->nlp_state; |
1226 | } | 1239 | } |
1227 | 1240 | ||
1228 | /* Check out PRLI rsp */ | 1241 | /* Check out PRLI rsp */ |
@@ -1238,9 +1251,10 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1238 | ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; | 1251 | ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; |
1239 | } | 1252 | } |
1240 | 1253 | ||
1254 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | ||
1241 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; | 1255 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; |
1242 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); | 1256 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); |
1243 | return (ndlp->nlp_state); | 1257 | return ndlp->nlp_state; |
1244 | } | 1258 | } |
1245 | 1259 | ||
1246 | /*! lpfc_device_rm_prli_issue | 1260 | /*! lpfc_device_rm_prli_issue |
@@ -1268,7 +1282,7 @@ lpfc_device_rm_prli_issue(struct lpfc_hba * phba, | |||
1268 | lpfc_els_abort(phba, ndlp, 1); | 1282 | lpfc_els_abort(phba, ndlp, 1); |
1269 | 1283 | ||
1270 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1284 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
1271 | return (NLP_STE_FREED_NODE); | 1285 | return NLP_STE_FREED_NODE; |
1272 | } | 1286 | } |
1273 | 1287 | ||
1274 | 1288 | ||
@@ -1295,12 +1309,13 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba, | |||
1295 | /* software abort outstanding PRLI */ | 1309 | /* software abort outstanding PRLI */ |
1296 | lpfc_els_abort(phba, ndlp, 1); | 1310 | lpfc_els_abort(phba, ndlp, 1); |
1297 | 1311 | ||
1312 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | ||
1298 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1313 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1299 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1314 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1300 | spin_lock_irq(phba->host->host_lock); | 1315 | spin_lock_irq(phba->host->host_lock); |
1301 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1316 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1302 | spin_unlock_irq(phba->host->host_lock); | 1317 | spin_unlock_irq(phba->host->host_lock); |
1303 | return (ndlp->nlp_state); | 1318 | return ndlp->nlp_state; |
1304 | } | 1319 | } |
1305 | 1320 | ||
1306 | static uint32_t | 1321 | static uint32_t |
@@ -1312,7 +1327,7 @@ lpfc_rcv_plogi_unmap_node(struct lpfc_hba * phba, | |||
1312 | cmdiocb = (struct lpfc_iocbq *) arg; | 1327 | cmdiocb = (struct lpfc_iocbq *) arg; |
1313 | 1328 | ||
1314 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1329 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); |
1315 | return (ndlp->nlp_state); | 1330 | return ndlp->nlp_state; |
1316 | } | 1331 | } |
1317 | 1332 | ||
1318 | static uint32_t | 1333 | static uint32_t |
@@ -1325,7 +1340,7 @@ lpfc_rcv_prli_unmap_node(struct lpfc_hba * phba, | |||
1325 | 1340 | ||
1326 | lpfc_rcv_prli(phba, ndlp, cmdiocb); | 1341 | lpfc_rcv_prli(phba, ndlp, cmdiocb); |
1327 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1342 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); |
1328 | return (ndlp->nlp_state); | 1343 | return ndlp->nlp_state; |
1329 | } | 1344 | } |
1330 | 1345 | ||
1331 | static uint32_t | 1346 | static uint32_t |
@@ -1337,7 +1352,7 @@ lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba, | |||
1337 | cmdiocb = (struct lpfc_iocbq *) arg; | 1352 | cmdiocb = (struct lpfc_iocbq *) arg; |
1338 | 1353 | ||
1339 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1354 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1340 | return (ndlp->nlp_state); | 1355 | return ndlp->nlp_state; |
1341 | } | 1356 | } |
1342 | 1357 | ||
1343 | static uint32_t | 1358 | static uint32_t |
@@ -1349,7 +1364,7 @@ lpfc_rcv_padisc_unmap_node(struct lpfc_hba * phba, | |||
1349 | cmdiocb = (struct lpfc_iocbq *) arg; | 1364 | cmdiocb = (struct lpfc_iocbq *) arg; |
1350 | 1365 | ||
1351 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1366 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
1352 | return (ndlp->nlp_state); | 1367 | return ndlp->nlp_state; |
1353 | } | 1368 | } |
1354 | 1369 | ||
1355 | static uint32_t | 1370 | static uint32_t |
@@ -1360,21 +1375,21 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba, | |||
1360 | 1375 | ||
1361 | cmdiocb = (struct lpfc_iocbq *) arg; | 1376 | cmdiocb = (struct lpfc_iocbq *) arg; |
1362 | 1377 | ||
1363 | /* Treat like rcv logo */ | 1378 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
1364 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1379 | return ndlp->nlp_state; |
1365 | return (ndlp->nlp_state); | ||
1366 | } | 1380 | } |
1367 | 1381 | ||
1368 | static uint32_t | 1382 | static uint32_t |
1369 | lpfc_device_recov_unmap_node(struct lpfc_hba * phba, | 1383 | lpfc_device_recov_unmap_node(struct lpfc_hba * phba, |
1370 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1384 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
1371 | { | 1385 | { |
1386 | ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; | ||
1372 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1387 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1373 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1388 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1374 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1389 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1375 | lpfc_disc_set_adisc(phba, ndlp); | 1390 | lpfc_disc_set_adisc(phba, ndlp); |
1376 | 1391 | ||
1377 | return (ndlp->nlp_state); | 1392 | return ndlp->nlp_state; |
1378 | } | 1393 | } |
1379 | 1394 | ||
1380 | static uint32_t | 1395 | static uint32_t |
@@ -1386,7 +1401,7 @@ lpfc_rcv_plogi_mapped_node(struct lpfc_hba * phba, | |||
1386 | cmdiocb = (struct lpfc_iocbq *) arg; | 1401 | cmdiocb = (struct lpfc_iocbq *) arg; |
1387 | 1402 | ||
1388 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1403 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); |
1389 | return (ndlp->nlp_state); | 1404 | return ndlp->nlp_state; |
1390 | } | 1405 | } |
1391 | 1406 | ||
1392 | static uint32_t | 1407 | static uint32_t |
@@ -1398,7 +1413,7 @@ lpfc_rcv_prli_mapped_node(struct lpfc_hba * phba, | |||
1398 | cmdiocb = (struct lpfc_iocbq *) arg; | 1413 | cmdiocb = (struct lpfc_iocbq *) arg; |
1399 | 1414 | ||
1400 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1415 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); |
1401 | return (ndlp->nlp_state); | 1416 | return ndlp->nlp_state; |
1402 | } | 1417 | } |
1403 | 1418 | ||
1404 | static uint32_t | 1419 | static uint32_t |
@@ -1410,7 +1425,7 @@ lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba, | |||
1410 | cmdiocb = (struct lpfc_iocbq *) arg; | 1425 | cmdiocb = (struct lpfc_iocbq *) arg; |
1411 | 1426 | ||
1412 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1427 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1413 | return (ndlp->nlp_state); | 1428 | return ndlp->nlp_state; |
1414 | } | 1429 | } |
1415 | 1430 | ||
1416 | static uint32_t | 1431 | static uint32_t |
@@ -1423,7 +1438,7 @@ lpfc_rcv_padisc_mapped_node(struct lpfc_hba * phba, | |||
1423 | cmdiocb = (struct lpfc_iocbq *) arg; | 1438 | cmdiocb = (struct lpfc_iocbq *) arg; |
1424 | 1439 | ||
1425 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1440 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); |
1426 | return (ndlp->nlp_state); | 1441 | return ndlp->nlp_state; |
1427 | } | 1442 | } |
1428 | 1443 | ||
1429 | static uint32_t | 1444 | static uint32_t |
@@ -1442,7 +1457,7 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba, | |||
1442 | 1457 | ||
1443 | /* Treat like rcv logo */ | 1458 | /* Treat like rcv logo */ |
1444 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1459 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1445 | return (ndlp->nlp_state); | 1460 | return ndlp->nlp_state; |
1446 | } | 1461 | } |
1447 | 1462 | ||
1448 | static uint32_t | 1463 | static uint32_t |
@@ -1450,13 +1465,14 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba, | |||
1450 | struct lpfc_nodelist * ndlp, void *arg, | 1465 | struct lpfc_nodelist * ndlp, void *arg, |
1451 | uint32_t evt) | 1466 | uint32_t evt) |
1452 | { | 1467 | { |
1468 | ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE; | ||
1453 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1469 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1454 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1470 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1455 | spin_lock_irq(phba->host->host_lock); | 1471 | spin_lock_irq(phba->host->host_lock); |
1456 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1472 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1457 | spin_unlock_irq(phba->host->host_lock); | 1473 | spin_unlock_irq(phba->host->host_lock); |
1458 | lpfc_disc_set_adisc(phba, ndlp); | 1474 | lpfc_disc_set_adisc(phba, ndlp); |
1459 | return (ndlp->nlp_state); | 1475 | return ndlp->nlp_state; |
1460 | } | 1476 | } |
1461 | 1477 | ||
1462 | static uint32_t | 1478 | static uint32_t |
@@ -1470,23 +1486,25 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba, | |||
1470 | 1486 | ||
1471 | /* Ignore PLOGI if we have an outstanding LOGO */ | 1487 | /* Ignore PLOGI if we have an outstanding LOGO */ |
1472 | if (ndlp->nlp_flag & NLP_LOGO_SND) { | 1488 | if (ndlp->nlp_flag & NLP_LOGO_SND) { |
1473 | return (ndlp->nlp_state); | 1489 | return ndlp->nlp_state; |
1474 | } | 1490 | } |
1475 | 1491 | ||
1476 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 1492 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { |
1477 | spin_lock_irq(phba->host->host_lock); | 1493 | spin_lock_irq(phba->host->host_lock); |
1478 | ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC); | 1494 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1479 | spin_unlock_irq(phba->host->host_lock); | 1495 | spin_unlock_irq(phba->host->host_lock); |
1480 | return (ndlp->nlp_state); | 1496 | return ndlp->nlp_state; |
1481 | } | 1497 | } |
1482 | 1498 | ||
1483 | /* send PLOGI immediately, move to PLOGI issue state */ | 1499 | /* send PLOGI immediately, move to PLOGI issue state */ |
1484 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1500 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1485 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1501 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1486 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1502 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1487 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1503 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1504 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | ||
1488 | } | 1505 | } |
1489 | return (ndlp->nlp_state); | 1506 | |
1507 | return ndlp->nlp_state; | ||
1490 | } | 1508 | } |
1491 | 1509 | ||
1492 | static uint32_t | 1510 | static uint32_t |
@@ -1506,16 +1524,22 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba, | |||
1506 | 1524 | ||
1507 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1525 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1508 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1526 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
1527 | spin_lock_irq(phba->host->host_lock); | ||
1528 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | ||
1529 | spin_unlock_irq(phba->host->host_lock); | ||
1530 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1509 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1531 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
1510 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | 1532 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); |
1511 | lpfc_issue_els_adisc(phba, ndlp, 0); | 1533 | lpfc_issue_els_adisc(phba, ndlp, 0); |
1512 | } else { | 1534 | } else { |
1535 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1513 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1536 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1514 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1537 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1515 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1538 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
1516 | } | 1539 | } |
1540 | |||
1517 | } | 1541 | } |
1518 | return (ndlp->nlp_state); | 1542 | return ndlp->nlp_state; |
1519 | } | 1543 | } |
1520 | 1544 | ||
1521 | static uint32_t | 1545 | static uint32_t |
@@ -1528,7 +1552,7 @@ lpfc_rcv_logo_npr_node(struct lpfc_hba * phba, | |||
1528 | cmdiocb = (struct lpfc_iocbq *) arg; | 1552 | cmdiocb = (struct lpfc_iocbq *) arg; |
1529 | 1553 | ||
1530 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1554 | lpfc_rcv_logo(phba, ndlp, cmdiocb); |
1531 | return (ndlp->nlp_state); | 1555 | return ndlp->nlp_state; |
1532 | } | 1556 | } |
1533 | 1557 | ||
1534 | static uint32_t | 1558 | static uint32_t |
@@ -1544,16 +1568,18 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, | |||
1544 | 1568 | ||
1545 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1569 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1546 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1570 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
1571 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1547 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1572 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
1548 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | 1573 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); |
1549 | lpfc_issue_els_adisc(phba, ndlp, 0); | 1574 | lpfc_issue_els_adisc(phba, ndlp, 0); |
1550 | } else { | 1575 | } else { |
1576 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1551 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1577 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1552 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1578 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1553 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1579 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
1554 | } | 1580 | } |
1555 | } | 1581 | } |
1556 | return (ndlp->nlp_state); | 1582 | return ndlp->nlp_state; |
1557 | } | 1583 | } |
1558 | 1584 | ||
1559 | static uint32_t | 1585 | static uint32_t |
@@ -1565,25 +1591,47 @@ lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba, | |||
1565 | 1591 | ||
1566 | cmdiocb = (struct lpfc_iocbq *) arg; | 1592 | cmdiocb = (struct lpfc_iocbq *) arg; |
1567 | 1593 | ||
1594 | spin_lock_irq(phba->host->host_lock); | ||
1595 | ndlp->nlp_flag |= NLP_LOGO_ACC; | ||
1596 | spin_unlock_irq(phba->host->host_lock); | ||
1597 | |||
1568 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1598 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
1569 | 1599 | ||
1570 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 1600 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1571 | if (ndlp->nlp_last_elscmd == (unsigned long)ELS_CMD_PLOGI) { | 1601 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
1572 | return (ndlp->nlp_state); | 1602 | spin_lock_irq(phba->host->host_lock); |
1573 | } else { | 1603 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1574 | spin_lock_irq(phba->host->host_lock); | 1604 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1575 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 1605 | spin_unlock_irq(phba->host->host_lock); |
1576 | spin_unlock_irq(phba->host->host_lock); | 1606 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
1577 | del_timer_sync(&ndlp->nlp_delayfunc); | 1607 | } else { |
1578 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | 1608 | spin_lock_irq(phba->host->host_lock); |
1579 | list_del_init(&ndlp->els_retry_evt.evt_listp); | 1609 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1580 | } | 1610 | spin_unlock_irq(phba->host->host_lock); |
1581 | } | 1611 | } |
1612 | return ndlp->nlp_state; | ||
1613 | } | ||
1582 | 1614 | ||
1583 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1615 | static uint32_t |
1584 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1616 | lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba, |
1585 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1617 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
1586 | return (ndlp->nlp_state); | 1618 | { |
1619 | struct lpfc_iocbq *cmdiocb, *rspiocb; | ||
1620 | |||
1621 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1622 | rspiocb = cmdiocb->context_un.rsp_iocb; | ||
1623 | return ndlp->nlp_state; | ||
1624 | } | ||
1625 | |||
1626 | static uint32_t | ||
1627 | lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba, | ||
1628 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | ||
1629 | { | ||
1630 | struct lpfc_iocbq *cmdiocb, *rspiocb; | ||
1631 | |||
1632 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1633 | rspiocb = cmdiocb->context_un.rsp_iocb; | ||
1634 | return ndlp->nlp_state; | ||
1587 | } | 1635 | } |
1588 | 1636 | ||
1589 | static uint32_t | 1637 | static uint32_t |
@@ -1592,7 +1640,19 @@ lpfc_cmpl_logo_npr_node(struct lpfc_hba * phba, | |||
1592 | { | 1640 | { |
1593 | lpfc_unreg_rpi(phba, ndlp); | 1641 | lpfc_unreg_rpi(phba, ndlp); |
1594 | /* This routine does nothing, just return the current state */ | 1642 | /* This routine does nothing, just return the current state */ |
1595 | return (ndlp->nlp_state); | 1643 | return ndlp->nlp_state; |
1644 | } | ||
1645 | |||
1646 | static uint32_t | ||
1647 | lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba, | ||
1648 | struct lpfc_nodelist * ndlp, void *arg, | ||
1649 | uint32_t evt) | ||
1650 | { | ||
1651 | struct lpfc_iocbq *cmdiocb, *rspiocb; | ||
1652 | |||
1653 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1654 | rspiocb = cmdiocb->context_un.rsp_iocb; | ||
1655 | return ndlp->nlp_state; | ||
1596 | } | 1656 | } |
1597 | 1657 | ||
1598 | static uint32_t | 1658 | static uint32_t |
@@ -1606,9 +1666,10 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, | |||
1606 | pmb = (LPFC_MBOXQ_t *) arg; | 1666 | pmb = (LPFC_MBOXQ_t *) arg; |
1607 | mb = &pmb->mb; | 1667 | mb = &pmb->mb; |
1608 | 1668 | ||
1609 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1669 | if (!mb->mbxStatus) |
1670 | ndlp->nlp_rpi = mb->un.varWords[0]; | ||
1610 | 1671 | ||
1611 | return (ndlp->nlp_state); | 1672 | return ndlp->nlp_state; |
1612 | } | 1673 | } |
1613 | 1674 | ||
1614 | static uint32_t | 1675 | static uint32_t |
@@ -1617,7 +1678,7 @@ lpfc_device_rm_npr_node(struct lpfc_hba * phba, | |||
1617 | uint32_t evt) | 1678 | uint32_t evt) |
1618 | { | 1679 | { |
1619 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1680 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
1620 | return (NLP_STE_FREED_NODE); | 1681 | return NLP_STE_FREED_NODE; |
1621 | } | 1682 | } |
1622 | 1683 | ||
1623 | static uint32_t | 1684 | static uint32_t |
@@ -1628,7 +1689,10 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba, | |||
1628 | spin_lock_irq(phba->host->host_lock); | 1689 | spin_lock_irq(phba->host->host_lock); |
1629 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1690 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1630 | spin_unlock_irq(phba->host->host_lock); | 1691 | spin_unlock_irq(phba->host->host_lock); |
1631 | return (ndlp->nlp_state); | 1692 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
1693 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | ||
1694 | } | ||
1695 | return ndlp->nlp_state; | ||
1632 | } | 1696 | } |
1633 | 1697 | ||
1634 | 1698 | ||
@@ -1707,7 +1771,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | |||
1707 | 1771 | ||
1708 | lpfc_rcv_plogi_plogi_issue, /* RCV_PLOGI PLOGI_ISSUE */ | 1772 | lpfc_rcv_plogi_plogi_issue, /* RCV_PLOGI PLOGI_ISSUE */ |
1709 | lpfc_rcv_els_plogi_issue, /* RCV_PRLI */ | 1773 | lpfc_rcv_els_plogi_issue, /* RCV_PRLI */ |
1710 | lpfc_rcv_els_plogi_issue, /* RCV_LOGO */ | 1774 | lpfc_rcv_logo_plogi_issue, /* RCV_LOGO */ |
1711 | lpfc_rcv_els_plogi_issue, /* RCV_ADISC */ | 1775 | lpfc_rcv_els_plogi_issue, /* RCV_ADISC */ |
1712 | lpfc_rcv_els_plogi_issue, /* RCV_PDISC */ | 1776 | lpfc_rcv_els_plogi_issue, /* RCV_PDISC */ |
1713 | lpfc_rcv_els_plogi_issue, /* RCV_PRLO */ | 1777 | lpfc_rcv_els_plogi_issue, /* RCV_PRLO */ |
@@ -1795,10 +1859,10 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | |||
1795 | lpfc_rcv_padisc_npr_node, /* RCV_ADISC */ | 1859 | lpfc_rcv_padisc_npr_node, /* RCV_ADISC */ |
1796 | lpfc_rcv_padisc_npr_node, /* RCV_PDISC */ | 1860 | lpfc_rcv_padisc_npr_node, /* RCV_PDISC */ |
1797 | lpfc_rcv_prlo_npr_node, /* RCV_PRLO */ | 1861 | lpfc_rcv_prlo_npr_node, /* RCV_PRLO */ |
1798 | lpfc_disc_noop, /* CMPL_PLOGI */ | 1862 | lpfc_cmpl_plogi_npr_node, /* CMPL_PLOGI */ |
1799 | lpfc_disc_noop, /* CMPL_PRLI */ | 1863 | lpfc_cmpl_prli_npr_node, /* CMPL_PRLI */ |
1800 | lpfc_cmpl_logo_npr_node, /* CMPL_LOGO */ | 1864 | lpfc_cmpl_logo_npr_node, /* CMPL_LOGO */ |
1801 | lpfc_disc_noop, /* CMPL_ADISC */ | 1865 | lpfc_cmpl_adisc_npr_node, /* CMPL_ADISC */ |
1802 | lpfc_cmpl_reglogin_npr_node, /* CMPL_REG_LOGIN */ | 1866 | lpfc_cmpl_reglogin_npr_node, /* CMPL_REG_LOGIN */ |
1803 | lpfc_device_rm_npr_node, /* DEVICE_RM */ | 1867 | lpfc_device_rm_npr_node, /* DEVICE_RM */ |
1804 | lpfc_device_recov_npr_node, /* DEVICE_RECOVERY */ | 1868 | lpfc_device_recov_npr_node, /* DEVICE_RECOVERY */ |
@@ -1844,10 +1908,9 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, | |||
1844 | ndlp->nlp_flag &= ~NLP_DELAY_REMOVE; | 1908 | ndlp->nlp_flag &= ~NLP_DELAY_REMOVE; |
1845 | spin_unlock_irq(phba->host->host_lock); | 1909 | spin_unlock_irq(phba->host->host_lock); |
1846 | lpfc_nlp_remove(phba, ndlp); | 1910 | lpfc_nlp_remove(phba, ndlp); |
1847 | return (NLP_STE_FREED_NODE); | 1911 | return NLP_STE_FREED_NODE; |
1848 | } | 1912 | } |
1849 | if (rc == NLP_STE_FREED_NODE) | 1913 | if (rc == NLP_STE_FREED_NODE) |
1850 | return (NLP_STE_FREED_NODE); | 1914 | return NLP_STE_FREED_NODE; |
1851 | ndlp->nlp_state = rc; | 1915 | return rc; |
1852 | return (rc); | ||
1853 | } | 1916 | } |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index dafabeefc5b3..f93799873721 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -467,7 +467,12 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
467 | sdev = cmd->device; | 467 | sdev = cmd->device; |
468 | cmd->scsi_done(cmd); | 468 | cmd->scsi_done(cmd); |
469 | 469 | ||
470 | if (!result && | 470 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
471 | lpfc_release_scsi_buf(phba, lpfc_cmd); | ||
472 | return; | ||
473 | } | ||
474 | |||
475 | if (!result && pnode != NULL && | ||
471 | ((jiffies - pnode->last_ramp_up_time) > | 476 | ((jiffies - pnode->last_ramp_up_time) > |
472 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && | 477 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && |
473 | ((jiffies - pnode->last_q_full_time) > | 478 | ((jiffies - pnode->last_q_full_time) > |
@@ -495,7 +500,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
495 | * Check for queue full. If the lun is reporting queue full, then | 500 | * Check for queue full. If the lun is reporting queue full, then |
496 | * back off the lun queue depth to prevent target overloads. | 501 | * back off the lun queue depth to prevent target overloads. |
497 | */ | 502 | */ |
498 | if (result == SAM_STAT_TASK_SET_FULL) { | 503 | if (result == SAM_STAT_TASK_SET_FULL && pnode != NULL) { |
499 | pnode->last_q_full_time = jiffies; | 504 | pnode->last_q_full_time = jiffies; |
500 | 505 | ||
501 | shost_for_each_device(tmp_sdev, sdev->host) { | 506 | shost_for_each_device(tmp_sdev, sdev->host) { |
@@ -743,7 +748,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) | |||
743 | const char * | 748 | const char * |
744 | lpfc_info(struct Scsi_Host *host) | 749 | lpfc_info(struct Scsi_Host *host) |
745 | { | 750 | { |
746 | struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0]; | 751 | struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata; |
747 | int len; | 752 | int len; |
748 | static char lpfcinfobuf[384]; | 753 | static char lpfcinfobuf[384]; |
749 | 754 | ||
@@ -803,7 +808,7 @@ static int | |||
803 | lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | 808 | lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) |
804 | { | 809 | { |
805 | struct lpfc_hba *phba = | 810 | struct lpfc_hba *phba = |
806 | (struct lpfc_hba *) cmnd->device->host->hostdata[0]; | 811 | (struct lpfc_hba *) cmnd->device->host->hostdata; |
807 | struct lpfc_sli *psli = &phba->sli; | 812 | struct lpfc_sli *psli = &phba->sli; |
808 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; | 813 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; |
809 | struct lpfc_nodelist *ndlp = rdata->pnode; | 814 | struct lpfc_nodelist *ndlp = rdata->pnode; |
@@ -877,7 +882,7 @@ static int | |||
877 | lpfc_abort_handler(struct scsi_cmnd *cmnd) | 882 | lpfc_abort_handler(struct scsi_cmnd *cmnd) |
878 | { | 883 | { |
879 | struct Scsi_Host *shost = cmnd->device->host; | 884 | struct Scsi_Host *shost = cmnd->device->host; |
880 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; | 885 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; |
881 | struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring]; | 886 | struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring]; |
882 | struct lpfc_iocbq *iocb; | 887 | struct lpfc_iocbq *iocb; |
883 | struct lpfc_iocbq *abtsiocb; | 888 | struct lpfc_iocbq *abtsiocb; |
@@ -981,7 +986,7 @@ static int | |||
981 | lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | 986 | lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) |
982 | { | 987 | { |
983 | struct Scsi_Host *shost = cmnd->device->host; | 988 | struct Scsi_Host *shost = cmnd->device->host; |
984 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; | 989 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; |
985 | struct lpfc_scsi_buf *lpfc_cmd; | 990 | struct lpfc_scsi_buf *lpfc_cmd; |
986 | struct lpfc_iocbq *iocbq, *iocbqrsp; | 991 | struct lpfc_iocbq *iocbq, *iocbqrsp; |
987 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; | 992 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; |
@@ -1094,7 +1099,7 @@ static int | |||
1094 | lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | 1099 | lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) |
1095 | { | 1100 | { |
1096 | struct Scsi_Host *shost = cmnd->device->host; | 1101 | struct Scsi_Host *shost = cmnd->device->host; |
1097 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0]; | 1102 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; |
1098 | struct lpfc_nodelist *ndlp = NULL; | 1103 | struct lpfc_nodelist *ndlp = NULL; |
1099 | int match; | 1104 | int match; |
1100 | int ret = FAILED, i, err_count = 0; | 1105 | int ret = FAILED, i, err_count = 0; |
@@ -1195,7 +1200,7 @@ out: | |||
1195 | static int | 1200 | static int |
1196 | lpfc_slave_alloc(struct scsi_device *sdev) | 1201 | lpfc_slave_alloc(struct scsi_device *sdev) |
1197 | { | 1202 | { |
1198 | struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0]; | 1203 | struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata; |
1199 | struct lpfc_scsi_buf *scsi_buf = NULL; | 1204 | struct lpfc_scsi_buf *scsi_buf = NULL; |
1200 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); | 1205 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); |
1201 | uint32_t total = 0, i; | 1206 | uint32_t total = 0, i; |
@@ -1251,7 +1256,7 @@ lpfc_slave_alloc(struct scsi_device *sdev) | |||
1251 | static int | 1256 | static int |
1252 | lpfc_slave_configure(struct scsi_device *sdev) | 1257 | lpfc_slave_configure(struct scsi_device *sdev) |
1253 | { | 1258 | { |
1254 | struct lpfc_hba *phba = (struct lpfc_hba *) sdev->host->hostdata[0]; | 1259 | struct lpfc_hba *phba = (struct lpfc_hba *) sdev->host->hostdata; |
1255 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); | 1260 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); |
1256 | 1261 | ||
1257 | if (sdev->tagged_supported) | 1262 | if (sdev->tagged_supported) |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index acd64c49e849..cdcd2535803f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.h | |||
@@ -23,10 +23,13 @@ | |||
23 | struct lpfc_hba; | 23 | struct lpfc_hba; |
24 | 24 | ||
25 | #define list_remove_head(list, entry, type, member) \ | 25 | #define list_remove_head(list, entry, type, member) \ |
26 | do { \ | ||
27 | entry = NULL; \ | ||
26 | if (!list_empty(list)) { \ | 28 | if (!list_empty(list)) { \ |
27 | entry = list_entry((list)->next, type, member); \ | 29 | entry = list_entry((list)->next, type, member); \ |
28 | list_del_init(&entry->member); \ | 30 | list_del_init(&entry->member); \ |
29 | } | 31 | } \ |
32 | } while(0) | ||
30 | 33 | ||
31 | #define list_get_first(list, type, member) \ | 34 | #define list_get_first(list, type, member) \ |
32 | (list_empty(list)) ? NULL : \ | 35 | (list_empty(list)) ? NULL : \ |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 7b785ade8b07..bb69a7a1ec59 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -513,7 +513,9 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
513 | case MBX_SET_MASK: | 513 | case MBX_SET_MASK: |
514 | case MBX_SET_SLIM: | 514 | case MBX_SET_SLIM: |
515 | case MBX_UNREG_D_ID: | 515 | case MBX_UNREG_D_ID: |
516 | case MBX_KILL_BOARD: | ||
516 | case MBX_CONFIG_FARP: | 517 | case MBX_CONFIG_FARP: |
518 | case MBX_BEACON: | ||
517 | case MBX_LOAD_AREA: | 519 | case MBX_LOAD_AREA: |
518 | case MBX_RUN_BIU_DIAG64: | 520 | case MBX_RUN_BIU_DIAG64: |
519 | case MBX_CONFIG_PORT: | 521 | case MBX_CONFIG_PORT: |
@@ -764,7 +766,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
764 | } | 766 | } |
765 | /* unSolicited Responses */ | 767 | /* unSolicited Responses */ |
766 | if (pring->prt[0].profile) { | 768 | if (pring->prt[0].profile) { |
767 | (pring->prt[0].lpfc_sli_rcv_unsol_event) (phba, pring, saveq); | 769 | if (pring->prt[0].lpfc_sli_rcv_unsol_event) |
770 | (pring->prt[0].lpfc_sli_rcv_unsol_event) (phba, pring, | ||
771 | saveq); | ||
768 | match = 1; | 772 | match = 1; |
769 | } else { | 773 | } else { |
770 | /* We must search, based on rctl / type | 774 | /* We must search, based on rctl / type |
@@ -775,8 +779,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
775 | Rctl) | 779 | Rctl) |
776 | && (pring->prt[i]. | 780 | && (pring->prt[i]. |
777 | type == Type)) { | 781 | type == Type)) { |
778 | (pring->prt[i].lpfc_sli_rcv_unsol_event) | 782 | if (pring->prt[i].lpfc_sli_rcv_unsol_event) |
779 | (phba, pring, saveq); | 783 | (pring->prt[i].lpfc_sli_rcv_unsol_event) |
784 | (phba, pring, saveq); | ||
780 | match = 1; | 785 | match = 1; |
781 | break; | 786 | break; |
782 | } | 787 | } |
@@ -1149,12 +1154,17 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, | |||
1149 | cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, | 1154 | cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, |
1150 | &rspiocbq); | 1155 | &rspiocbq); |
1151 | if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { | 1156 | if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { |
1152 | spin_unlock_irqrestore( | 1157 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
1153 | phba->host->host_lock, iflag); | 1158 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, |
1154 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, | 1159 | &rspiocbq); |
1155 | &rspiocbq); | 1160 | } else { |
1156 | spin_lock_irqsave(phba->host->host_lock, | 1161 | spin_unlock_irqrestore( |
1157 | iflag); | 1162 | phba->host->host_lock, iflag); |
1163 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, | ||
1164 | &rspiocbq); | ||
1165 | spin_lock_irqsave(phba->host->host_lock, | ||
1166 | iflag); | ||
1167 | } | ||
1158 | } | 1168 | } |
1159 | break; | 1169 | break; |
1160 | default: | 1170 | default: |
@@ -1512,98 +1522,240 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
1512 | return errcnt; | 1522 | return errcnt; |
1513 | } | 1523 | } |
1514 | 1524 | ||
1515 | /****************************************************************************** | 1525 | int |
1516 | * lpfc_sli_send_reset | 1526 | lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask) |
1517 | * | ||
1518 | * Note: After returning from this function, the HBA cannot be accessed for | ||
1519 | * 1 ms. Since we do not wish to delay in interrupt context, it is the | ||
1520 | * responsibility of the caller to perform the mdelay(1) and flush via readl(). | ||
1521 | ******************************************************************************/ | ||
1522 | static int | ||
1523 | lpfc_sli_send_reset(struct lpfc_hba * phba, uint16_t skip_post) | ||
1524 | { | 1527 | { |
1525 | MAILBOX_t *swpmb; | 1528 | uint32_t status; |
1526 | volatile uint32_t word0; | 1529 | int i = 0; |
1527 | void __iomem *to_slim; | 1530 | int retval = 0; |
1528 | unsigned long flags = 0; | ||
1529 | |||
1530 | spin_lock_irqsave(phba->host->host_lock, flags); | ||
1531 | 1531 | ||
1532 | /* A board reset must use REAL SLIM. */ | 1532 | /* Read the HBA Host Status Register */ |
1533 | phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE; | 1533 | status = readl(phba->HSregaddr); |
1534 | 1534 | ||
1535 | word0 = 0; | 1535 | /* |
1536 | swpmb = (MAILBOX_t *) & word0; | 1536 | * Check status register every 100ms for 5 retries, then every |
1537 | swpmb->mbxCommand = MBX_RESTART; | 1537 | * 500ms for 5, then every 2.5 sec for 5, then reset board and |
1538 | swpmb->mbxHc = 1; | 1538 | * every 2.5 sec for 4. |
1539 | * Break our of the loop if errors occurred during init. | ||
1540 | */ | ||
1541 | while (((status & mask) != mask) && | ||
1542 | !(status & HS_FFERM) && | ||
1543 | i++ < 20) { | ||
1539 | 1544 | ||
1540 | to_slim = phba->MBslimaddr; | 1545 | if (i <= 5) |
1541 | writel(*(uint32_t *) swpmb, to_slim); | 1546 | msleep(10); |
1542 | readl(to_slim); /* flush */ | 1547 | else if (i <= 10) |
1548 | msleep(500); | ||
1549 | else | ||
1550 | msleep(2500); | ||
1543 | 1551 | ||
1544 | /* Only skip post after fc_ffinit is completed */ | 1552 | if (i == 15) { |
1545 | if (skip_post) { | 1553 | phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */ |
1546 | word0 = 1; /* This is really setting up word1 */ | 1554 | lpfc_sli_brdrestart(phba); |
1547 | } else { | 1555 | } |
1548 | word0 = 0; /* This is really setting up word1 */ | 1556 | /* Read the HBA Host Status Register */ |
1557 | status = readl(phba->HSregaddr); | ||
1549 | } | 1558 | } |
1550 | to_slim = phba->MBslimaddr + sizeof (uint32_t); | ||
1551 | writel(*(uint32_t *) swpmb, to_slim); | ||
1552 | readl(to_slim); /* flush */ | ||
1553 | |||
1554 | /* Turn off parity checking and serr during the physical reset */ | ||
1555 | pci_read_config_word(phba->pcidev, PCI_COMMAND, &phba->pci_cfg_value); | ||
1556 | pci_write_config_word(phba->pcidev, PCI_COMMAND, | ||
1557 | (phba->pci_cfg_value & | ||
1558 | ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); | ||
1559 | |||
1560 | writel(HC_INITFF, phba->HCregaddr); | ||
1561 | 1559 | ||
1562 | phba->hba_state = LPFC_INIT_START; | 1560 | /* Check to see if any errors occurred during init */ |
1563 | spin_unlock_irqrestore(phba->host->host_lock, flags); | 1561 | if ((status & HS_FFERM) || (i >= 20)) { |
1562 | phba->hba_state = LPFC_HBA_ERROR; | ||
1563 | retval = 1; | ||
1564 | } | ||
1564 | 1565 | ||
1565 | return 0; | 1566 | return retval; |
1566 | } | 1567 | } |
1567 | 1568 | ||
1568 | static int | 1569 | #define BARRIER_TEST_PATTERN (0xdeadbeef) |
1569 | lpfc_sli_brdreset(struct lpfc_hba * phba, uint16_t skip_post) | 1570 | |
1571 | void lpfc_reset_barrier(struct lpfc_hba * phba) | ||
1570 | { | 1572 | { |
1571 | struct lpfc_sli_ring *pring; | 1573 | uint32_t * resp_buf; |
1572 | int i; | 1574 | uint32_t * mbox_buf; |
1573 | struct lpfc_dmabuf *mp, *next_mp; | 1575 | volatile uint32_t mbox; |
1574 | unsigned long flags = 0; | 1576 | uint32_t hc_copy; |
1577 | int i; | ||
1578 | uint8_t hdrtype; | ||
1579 | |||
1580 | pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype); | ||
1581 | if (hdrtype != 0x80 || | ||
1582 | (FC_JEDEC_ID(phba->vpd.rev.biuRev) != HELIOS_JEDEC_ID && | ||
1583 | FC_JEDEC_ID(phba->vpd.rev.biuRev) != THOR_JEDEC_ID)) | ||
1584 | return; | ||
1575 | 1585 | ||
1576 | lpfc_sli_send_reset(phba, skip_post); | 1586 | /* |
1577 | mdelay(1); | 1587 | * Tell the other part of the chip to suspend temporarily all |
1588 | * its DMA activity. | ||
1589 | */ | ||
1590 | resp_buf = (uint32_t *)phba->MBslimaddr; | ||
1578 | 1591 | ||
1579 | spin_lock_irqsave(phba->host->host_lock, flags); | 1592 | /* Disable the error attention */ |
1580 | /* Risk the write on flush case ie no delay after the readl */ | 1593 | hc_copy = readl(phba->HCregaddr); |
1594 | writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr); | ||
1581 | readl(phba->HCregaddr); /* flush */ | 1595 | readl(phba->HCregaddr); /* flush */ |
1582 | /* Now toggle INITFF bit set by lpfc_sli_send_reset */ | 1596 | |
1583 | writel(0, phba->HCregaddr); | 1597 | if (readl(phba->HAregaddr) & HA_ERATT) { |
1598 | /* Clear Chip error bit */ | ||
1599 | writel(HA_ERATT, phba->HAregaddr); | ||
1600 | phba->stopped = 1; | ||
1601 | } | ||
1602 | |||
1603 | mbox = 0; | ||
1604 | ((MAILBOX_t *)&mbox)->mbxCommand = MBX_KILL_BOARD; | ||
1605 | ((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP; | ||
1606 | |||
1607 | writel(BARRIER_TEST_PATTERN, (resp_buf + 1)); | ||
1608 | mbox_buf = (uint32_t *)phba->MBslimaddr; | ||
1609 | writel(mbox, mbox_buf); | ||
1610 | |||
1611 | for (i = 0; | ||
1612 | readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN) && i < 50; i++) | ||
1613 | mdelay(1); | ||
1614 | |||
1615 | if (readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN)) { | ||
1616 | if (phba->sli.sli_flag & LPFC_SLI2_ACTIVE || | ||
1617 | phba->stopped) | ||
1618 | goto restore_hc; | ||
1619 | else | ||
1620 | goto clear_errat; | ||
1621 | } | ||
1622 | |||
1623 | ((MAILBOX_t *)&mbox)->mbxOwner = OWN_HOST; | ||
1624 | for (i = 0; readl(resp_buf) != mbox && i < 500; i++) | ||
1625 | mdelay(1); | ||
1626 | |||
1627 | clear_errat: | ||
1628 | |||
1629 | while (!(readl(phba->HAregaddr) & HA_ERATT) && ++i < 500) | ||
1630 | mdelay(1); | ||
1631 | |||
1632 | if (readl(phba->HAregaddr) & HA_ERATT) { | ||
1633 | writel(HA_ERATT, phba->HAregaddr); | ||
1634 | phba->stopped = 1; | ||
1635 | } | ||
1636 | |||
1637 | restore_hc: | ||
1638 | writel(hc_copy, phba->HCregaddr); | ||
1584 | readl(phba->HCregaddr); /* flush */ | 1639 | readl(phba->HCregaddr); /* flush */ |
1640 | } | ||
1585 | 1641 | ||
1586 | /* Restore PCI cmd register */ | 1642 | int |
1587 | pci_write_config_word(phba->pcidev, PCI_COMMAND, phba->pci_cfg_value); | 1643 | lpfc_sli_brdkill(struct lpfc_hba * phba) |
1644 | { | ||
1645 | struct lpfc_sli *psli; | ||
1646 | LPFC_MBOXQ_t *pmb; | ||
1647 | uint32_t status; | ||
1648 | uint32_t ha_copy; | ||
1649 | int retval; | ||
1650 | int i = 0; | ||
1588 | 1651 | ||
1589 | /* perform board reset */ | 1652 | psli = &phba->sli; |
1590 | phba->fc_eventTag = 0; | ||
1591 | phba->fc_myDID = 0; | ||
1592 | phba->fc_prevDID = Mask_DID; | ||
1593 | 1653 | ||
1594 | /* Reset HBA */ | 1654 | /* Kill HBA */ |
1595 | lpfc_printf_log(phba, | 1655 | lpfc_printf_log(phba, |
1596 | KERN_INFO, | 1656 | KERN_INFO, |
1597 | LOG_SLI, | 1657 | LOG_SLI, |
1598 | "%d:0325 Reset HBA Data: x%x x%x x%x\n", | 1658 | "%d:0329 Kill HBA Data: x%x x%x\n", |
1599 | phba->brd_no, | 1659 | phba->brd_no, |
1600 | phba->hba_state, | 1660 | phba->hba_state, |
1601 | phba->sli.sli_flag, | 1661 | psli->sli_flag); |
1602 | skip_post); | 1662 | |
1663 | if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, | ||
1664 | GFP_KERNEL)) == 0) | ||
1665 | return 1; | ||
1666 | |||
1667 | /* Disable the error attention */ | ||
1668 | spin_lock_irq(phba->host->host_lock); | ||
1669 | status = readl(phba->HCregaddr); | ||
1670 | status &= ~HC_ERINT_ENA; | ||
1671 | writel(status, phba->HCregaddr); | ||
1672 | readl(phba->HCregaddr); /* flush */ | ||
1673 | spin_unlock_irq(phba->host->host_lock); | ||
1674 | |||
1675 | lpfc_kill_board(phba, pmb); | ||
1676 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | ||
1677 | retval = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | ||
1678 | |||
1679 | if (retval != MBX_SUCCESS) { | ||
1680 | if (retval != MBX_BUSY) | ||
1681 | mempool_free(pmb, phba->mbox_mem_pool); | ||
1682 | return 1; | ||
1683 | } | ||
1684 | |||
1685 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
1686 | |||
1687 | mempool_free(pmb, phba->mbox_mem_pool); | ||
1688 | |||
1689 | /* There is no completion for a KILL_BOARD mbox cmd. Check for an error | ||
1690 | * attention every 100ms for 3 seconds. If we don't get ERATT after | ||
1691 | * 3 seconds we still set HBA_ERROR state because the status of the | ||
1692 | * board is now undefined. | ||
1693 | */ | ||
1694 | ha_copy = readl(phba->HAregaddr); | ||
1695 | |||
1696 | while ((i++ < 30) && !(ha_copy & HA_ERATT)) { | ||
1697 | mdelay(100); | ||
1698 | ha_copy = readl(phba->HAregaddr); | ||
1699 | } | ||
1700 | |||
1701 | del_timer_sync(&psli->mbox_tmo); | ||
1702 | if (ha_copy & HA_ERATT) { | ||
1703 | writel(HA_ERATT, phba->HAregaddr); | ||
1704 | phba->stopped = 1; | ||
1705 | } | ||
1706 | spin_lock_irq(phba->host->host_lock); | ||
1707 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
1708 | spin_unlock_irq(phba->host->host_lock); | ||
1709 | |||
1710 | psli->mbox_active = NULL; | ||
1711 | lpfc_hba_down_post(phba); | ||
1712 | phba->hba_state = LPFC_HBA_ERROR; | ||
1713 | |||
1714 | return (ha_copy & HA_ERATT ? 0 : 1); | ||
1715 | } | ||
1716 | |||
1717 | int | ||
1718 | lpfc_sli_brdreset(struct lpfc_hba * phba) | ||
1719 | { | ||
1720 | struct lpfc_sli *psli; | ||
1721 | struct lpfc_sli_ring *pring; | ||
1722 | uint16_t cfg_value; | ||
1723 | int i; | ||
1724 | |||
1725 | psli = &phba->sli; | ||
1726 | |||
1727 | /* Reset HBA */ | ||
1728 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
1729 | "%d:0325 Reset HBA Data: x%x x%x\n", phba->brd_no, | ||
1730 | phba->hba_state, psli->sli_flag); | ||
1731 | |||
1732 | /* perform board reset */ | ||
1733 | phba->fc_eventTag = 0; | ||
1734 | phba->fc_myDID = 0; | ||
1735 | phba->fc_prevDID = 0; | ||
1736 | |||
1737 | psli->sli_flag = 0; | ||
1738 | |||
1739 | /* Turn off parity checking and serr during the physical reset */ | ||
1740 | pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value); | ||
1741 | pci_write_config_word(phba->pcidev, PCI_COMMAND, | ||
1742 | (cfg_value & | ||
1743 | ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); | ||
1744 | |||
1745 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
1746 | /* Now toggle INITFF bit in the Host Control Register */ | ||
1747 | writel(HC_INITFF, phba->HCregaddr); | ||
1748 | mdelay(1); | ||
1749 | readl(phba->HCregaddr); /* flush */ | ||
1750 | writel(0, phba->HCregaddr); | ||
1751 | readl(phba->HCregaddr); /* flush */ | ||
1752 | |||
1753 | /* Restore PCI cmd register */ | ||
1754 | pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value); | ||
1603 | 1755 | ||
1604 | /* Initialize relevant SLI info */ | 1756 | /* Initialize relevant SLI info */ |
1605 | for (i = 0; i < phba->sli.num_rings; i++) { | 1757 | for (i = 0; i < psli->num_rings; i++) { |
1606 | pring = &phba->sli.ring[i]; | 1758 | pring = &psli->ring[i]; |
1607 | pring->flag = 0; | 1759 | pring->flag = 0; |
1608 | pring->rspidx = 0; | 1760 | pring->rspidx = 0; |
1609 | pring->next_cmdidx = 0; | 1761 | pring->next_cmdidx = 0; |
@@ -1611,27 +1763,64 @@ lpfc_sli_brdreset(struct lpfc_hba * phba, uint16_t skip_post) | |||
1611 | pring->cmdidx = 0; | 1763 | pring->cmdidx = 0; |
1612 | pring->missbufcnt = 0; | 1764 | pring->missbufcnt = 0; |
1613 | } | 1765 | } |
1614 | spin_unlock_irqrestore(phba->host->host_lock, flags); | ||
1615 | 1766 | ||
1616 | if (skip_post) { | 1767 | phba->hba_state = LPFC_WARM_START; |
1617 | mdelay(100); | 1768 | return 0; |
1769 | } | ||
1770 | |||
1771 | int | ||
1772 | lpfc_sli_brdrestart(struct lpfc_hba * phba) | ||
1773 | { | ||
1774 | MAILBOX_t *mb; | ||
1775 | struct lpfc_sli *psli; | ||
1776 | uint16_t skip_post; | ||
1777 | volatile uint32_t word0; | ||
1778 | void __iomem *to_slim; | ||
1779 | |||
1780 | spin_lock_irq(phba->host->host_lock); | ||
1781 | |||
1782 | psli = &phba->sli; | ||
1783 | |||
1784 | /* Restart HBA */ | ||
1785 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
1786 | "%d:0328 Restart HBA Data: x%x x%x\n", phba->brd_no, | ||
1787 | phba->hba_state, psli->sli_flag); | ||
1788 | |||
1789 | word0 = 0; | ||
1790 | mb = (MAILBOX_t *) &word0; | ||
1791 | mb->mbxCommand = MBX_RESTART; | ||
1792 | mb->mbxHc = 1; | ||
1793 | |||
1794 | lpfc_reset_barrier(phba); | ||
1795 | |||
1796 | to_slim = phba->MBslimaddr; | ||
1797 | writel(*(uint32_t *) mb, to_slim); | ||
1798 | readl(to_slim); /* flush */ | ||
1799 | |||
1800 | /* Only skip post after fc_ffinit is completed */ | ||
1801 | if (phba->hba_state) { | ||
1802 | skip_post = 1; | ||
1803 | word0 = 1; /* This is really setting up word1 */ | ||
1618 | } else { | 1804 | } else { |
1619 | mdelay(2000); | 1805 | skip_post = 0; |
1806 | word0 = 0; /* This is really setting up word1 */ | ||
1620 | } | 1807 | } |
1808 | to_slim = (uint8_t *) phba->MBslimaddr + sizeof (uint32_t); | ||
1809 | writel(*(uint32_t *) mb, to_slim); | ||
1810 | readl(to_slim); /* flush */ | ||
1621 | 1811 | ||
1622 | spin_lock_irqsave(phba->host->host_lock, flags); | 1812 | lpfc_sli_brdreset(phba); |
1623 | /* Cleanup preposted buffers on the ELS ring */ | 1813 | phba->stopped = 0; |
1624 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 1814 | phba->hba_state = LPFC_INIT_START; |
1625 | list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { | 1815 | |
1626 | list_del(&mp->list); | 1816 | spin_unlock_irq(phba->host->host_lock); |
1627 | pring->postbufq_cnt--; | 1817 | |
1628 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1818 | if (skip_post) |
1629 | kfree(mp); | 1819 | mdelay(100); |
1630 | } | 1820 | else |
1631 | spin_unlock_irqrestore(phba->host->host_lock, flags); | 1821 | mdelay(2000); |
1632 | 1822 | ||
1633 | for (i = 0; i < phba->sli.num_rings; i++) | 1823 | lpfc_hba_down_post(phba); |
1634 | lpfc_sli_abort_iocb_ring(phba, &phba->sli.ring[i]); | ||
1635 | 1824 | ||
1636 | return 0; | 1825 | return 0; |
1637 | } | 1826 | } |
@@ -1691,7 +1880,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
1691 | } | 1880 | } |
1692 | 1881 | ||
1693 | if (i == 15) { | 1882 | if (i == 15) { |
1694 | lpfc_sli_brdreset(phba, 0); | 1883 | phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */ |
1884 | lpfc_sli_brdrestart(phba); | ||
1695 | } | 1885 | } |
1696 | /* Read the HBA Host Status Register */ | 1886 | /* Read the HBA Host Status Register */ |
1697 | status = readl(phba->HSregaddr); | 1887 | status = readl(phba->HSregaddr); |
@@ -1735,8 +1925,8 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba) | |||
1735 | } | 1925 | } |
1736 | 1926 | ||
1737 | while (resetcount < 2 && !done) { | 1927 | while (resetcount < 2 && !done) { |
1738 | phba->hba_state = 0; | 1928 | phba->hba_state = LPFC_STATE_UNKNOWN; |
1739 | lpfc_sli_brdreset(phba, 0); | 1929 | lpfc_sli_brdrestart(phba); |
1740 | msleep(2500); | 1930 | msleep(2500); |
1741 | rc = lpfc_sli_chipset_init(phba); | 1931 | rc = lpfc_sli_chipset_init(phba); |
1742 | if (rc) | 1932 | if (rc) |
@@ -1920,6 +2110,21 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
1920 | mb = &pmbox->mb; | 2110 | mb = &pmbox->mb; |
1921 | status = MBX_SUCCESS; | 2111 | status = MBX_SUCCESS; |
1922 | 2112 | ||
2113 | if (phba->hba_state == LPFC_HBA_ERROR) { | ||
2114 | spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); | ||
2115 | |||
2116 | /* Mbox command <mbxCommand> cannot issue */ | ||
2117 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) | ||
2118 | return (MBX_NOT_FINISHED); | ||
2119 | } | ||
2120 | |||
2121 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && | ||
2122 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { | ||
2123 | spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); | ||
2124 | LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag) | ||
2125 | return (MBX_NOT_FINISHED); | ||
2126 | } | ||
2127 | |||
1923 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { | 2128 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { |
1924 | /* Polling for a mbox command when another one is already active | 2129 | /* Polling for a mbox command when another one is already active |
1925 | * is not allowed in SLI. Also, the driver must have established | 2130 | * is not allowed in SLI. Also, the driver must have established |
@@ -2002,7 +2207,8 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2002 | 2207 | ||
2003 | /* If we are not polling, we MUST be in SLI2 mode */ | 2208 | /* If we are not polling, we MUST be in SLI2 mode */ |
2004 | if (flag != MBX_POLL) { | 2209 | if (flag != MBX_POLL) { |
2005 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { | 2210 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE) && |
2211 | (mb->mbxCommand != MBX_KILL_BOARD)) { | ||
2006 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2212 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2007 | spin_unlock_irqrestore(phba->host->host_lock, | 2213 | spin_unlock_irqrestore(phba->host->host_lock, |
2008 | drvr_flag); | 2214 | drvr_flag); |
@@ -2086,8 +2292,9 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2086 | ha_copy = readl(phba->HAregaddr); | 2292 | ha_copy = readl(phba->HAregaddr); |
2087 | 2293 | ||
2088 | /* Wait for command to complete */ | 2294 | /* Wait for command to complete */ |
2089 | while (((word0 & OWN_CHIP) == OWN_CHIP) | 2295 | while (((word0 & OWN_CHIP) == OWN_CHIP) || |
2090 | || !(ha_copy & HA_MBATT)) { | 2296 | (!(ha_copy & HA_MBATT) && |
2297 | (phba->hba_state > LPFC_WARM_START))) { | ||
2091 | if (i++ >= 100) { | 2298 | if (i++ >= 100) { |
2092 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2299 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2093 | spin_unlock_irqrestore(phba->host->host_lock, | 2300 | spin_unlock_irqrestore(phba->host->host_lock, |
@@ -2237,16 +2444,6 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2237 | !(phba->sli.sli_flag & LPFC_PROCESS_LA))) | 2444 | !(phba->sli.sli_flag & LPFC_PROCESS_LA))) |
2238 | goto iocb_busy; | 2445 | goto iocb_busy; |
2239 | 2446 | ||
2240 | /* | ||
2241 | * Check to see if this is a high priority command. | ||
2242 | * If so bypass tx queue processing. | ||
2243 | */ | ||
2244 | if (unlikely((flag & SLI_IOCB_HIGH_PRIORITY) && | ||
2245 | (iocb = lpfc_sli_next_iocb_slot(phba, pring)))) { | ||
2246 | lpfc_sli_submit_iocb(phba, pring, iocb, piocb); | ||
2247 | piocb = NULL; | ||
2248 | } | ||
2249 | |||
2250 | while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) && | 2447 | while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) && |
2251 | (nextiocb = lpfc_sli_next_iocb(phba, pring, &piocb))) | 2448 | (nextiocb = lpfc_sli_next_iocb(phba, pring, &piocb))) |
2252 | lpfc_sli_submit_iocb(phba, pring, iocb, nextiocb); | 2449 | lpfc_sli_submit_iocb(phba, pring, iocb, nextiocb); |
@@ -2274,6 +2471,37 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2274 | return IOCB_BUSY; | 2471 | return IOCB_BUSY; |
2275 | } | 2472 | } |
2276 | 2473 | ||
2474 | static int | ||
2475 | lpfc_extra_ring_setup( struct lpfc_hba *phba) | ||
2476 | { | ||
2477 | struct lpfc_sli *psli; | ||
2478 | struct lpfc_sli_ring *pring; | ||
2479 | |||
2480 | psli = &phba->sli; | ||
2481 | |||
2482 | /* Adjust cmd/rsp ring iocb entries more evenly */ | ||
2483 | pring = &psli->ring[psli->fcp_ring]; | ||
2484 | pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES; | ||
2485 | pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES; | ||
2486 | pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES; | ||
2487 | pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES; | ||
2488 | |||
2489 | pring = &psli->ring[1]; | ||
2490 | pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES; | ||
2491 | pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES; | ||
2492 | pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES; | ||
2493 | pring->numRiocb += SLI2_IOCB_RSP_R3XTRA_ENTRIES; | ||
2494 | |||
2495 | /* Setup default profile for this ring */ | ||
2496 | pring->iotag_max = 4096; | ||
2497 | pring->num_mask = 1; | ||
2498 | pring->prt[0].profile = 0; /* Mask 0 */ | ||
2499 | pring->prt[0].rctl = FC_UNSOL_DATA; | ||
2500 | pring->prt[0].type = 5; | ||
2501 | pring->prt[0].lpfc_sli_rcv_unsol_event = NULL; | ||
2502 | return 0; | ||
2503 | } | ||
2504 | |||
2277 | int | 2505 | int |
2278 | lpfc_sli_setup(struct lpfc_hba *phba) | 2506 | lpfc_sli_setup(struct lpfc_hba *phba) |
2279 | { | 2507 | { |
@@ -2357,6 +2585,8 @@ lpfc_sli_setup(struct lpfc_hba *phba) | |||
2357 | "SLI2 SLIM Data: x%x x%x\n", | 2585 | "SLI2 SLIM Data: x%x x%x\n", |
2358 | phba->brd_no, totiocb, MAX_SLI2_IOCB); | 2586 | phba->brd_no, totiocb, MAX_SLI2_IOCB); |
2359 | } | 2587 | } |
2588 | if (phba->cfg_multi_ring_support == 2) | ||
2589 | lpfc_extra_ring_setup(phba); | ||
2360 | 2590 | ||
2361 | return 0; | 2591 | return 0; |
2362 | } | 2592 | } |
@@ -2465,15 +2695,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) | |||
2465 | 2695 | ||
2466 | spin_unlock_irqrestore(phba->host->host_lock, flags); | 2696 | spin_unlock_irqrestore(phba->host->host_lock, flags); |
2467 | 2697 | ||
2468 | /* | ||
2469 | * Provided the hba is not in an error state, reset it. It is not | ||
2470 | * capable of IO anymore. | ||
2471 | */ | ||
2472 | if (phba->hba_state != LPFC_HBA_ERROR) { | ||
2473 | phba->hba_state = LPFC_INIT_START; | ||
2474 | lpfc_sli_brdreset(phba, 1); | ||
2475 | } | ||
2476 | |||
2477 | return 1; | 2698 | return 1; |
2478 | } | 2699 | } |
2479 | 2700 | ||
@@ -2877,11 +3098,10 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | |||
2877 | pmboxq->context1 = NULL; | 3098 | pmboxq->context1 = NULL; |
2878 | /* if schedule_timeout returns 0, we timed out and were not | 3099 | /* if schedule_timeout returns 0, we timed out and were not |
2879 | woken up */ | 3100 | woken up */ |
2880 | if (timeleft == 0) { | 3101 | if ((timeleft == 0) || signal_pending(current)) |
2881 | retval = MBX_TIMEOUT; | 3102 | retval = MBX_TIMEOUT; |
2882 | } else { | 3103 | else |
2883 | retval = MBX_SUCCESS; | 3104 | retval = MBX_SUCCESS; |
2884 | } | ||
2885 | } | 3105 | } |
2886 | 3106 | ||
2887 | 3107 | ||
@@ -2987,13 +3207,7 @@ lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs) | |||
2987 | /* Clear Chip error bit */ | 3207 | /* Clear Chip error bit */ |
2988 | writel(HA_ERATT, phba->HAregaddr); | 3208 | writel(HA_ERATT, phba->HAregaddr); |
2989 | readl(phba->HAregaddr); /* flush */ | 3209 | readl(phba->HAregaddr); /* flush */ |
2990 | 3210 | phba->stopped = 1; | |
2991 | /* | ||
2992 | * Reseting the HBA is the only reliable way | ||
2993 | * to shutdown interrupt when there is a | ||
2994 | * ERROR. | ||
2995 | */ | ||
2996 | lpfc_sli_send_reset(phba, phba->hba_state); | ||
2997 | } | 3211 | } |
2998 | 3212 | ||
2999 | spin_lock(phba->host->host_lock); | 3213 | spin_lock(phba->host->host_lock); |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index b7a9f970f565..a52d6c6cf083 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -61,7 +61,6 @@ struct lpfc_iocbq { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | #define SLI_IOCB_RET_IOCB 1 /* Return IOCB if cmd ring full */ | 63 | #define SLI_IOCB_RET_IOCB 1 /* Return IOCB if cmd ring full */ |
64 | #define SLI_IOCB_HIGH_PRIORITY 2 /* High priority command */ | ||
65 | 64 | ||
66 | #define IOCB_SUCCESS 0 | 65 | #define IOCB_SUCCESS 0 |
67 | #define IOCB_BUSY 1 | 66 | #define IOCB_BUSY 1 |
@@ -200,8 +199,6 @@ struct lpfc_sli { | |||
200 | struct timer_list mbox_tmo; /* Hold clk to timeout active mbox | 199 | struct timer_list mbox_tmo; /* Hold clk to timeout active mbox |
201 | cmd */ | 200 | cmd */ |
202 | 201 | ||
203 | uint32_t *MBhostaddr; /* virtual address for mbox cmds */ | ||
204 | |||
205 | #define LPFC_IOCBQ_LOOKUP_INCREMENT 1024 | 202 | #define LPFC_IOCBQ_LOOKUP_INCREMENT 1024 |
206 | struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */ | 203 | struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */ |
207 | size_t iocbq_lookup_len; /* current lengs of the array */ | 204 | size_t iocbq_lookup_len; /* current lengs of the array */ |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index fa681a934ffe..4cf1366108b7 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-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -18,12 +18,12 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.1.1" | 21 | #define LPFC_DRIVER_VERSION "8.1.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-2005 Emulex. All rights reserved." | 27 | #define LPFC_COPYRIGHT "Copyright(c) 2004-2006 Emulex. All rights reserved." |
28 | 28 | ||
29 | #define DFC_API_VERSION "0.0.0" | 29 | #define DFC_API_VERSION "0.0.0" |