aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-10-27 13:37:53 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:22:33 -0500
commita8adb83208020c913f010cb4e26d09e25300db8e (patch)
tree2245ca9f0dba5139946c99d45b80e7f2ce324b74 /drivers/scsi
parent87af33fe5f78c27cf9e43c6e586dd6efd4be3e40 (diff)
[SCSI] lpfc 8.2.3 : Miscellaneous Small Fixes - part 2
Miscellaneous Small Fixes - part 2 - Fix ndlp left in PLOGI state after link up - Fix cannot rcv unsol ELS frames after running HBA resets for a few minutes - Fix HBQ buffer_count implemention - Fix RPI leak - Fix crash while deleting vports while HBA is reset - Revert the FCP Fbits offset back to 7 - Fix panic when deleting vports - Remove unused code in switch statement outside of a case - Reject PLOGI from invalid PName or NName of 0 - Ignore PLOGI responses from WWPName or WWNName of 0 - Fix debugfs hbqinfo display for ppc - Added 8G to list of supported speeds for sysfs parameter - Defer ndlp cleanup to dev-loss timeout handler - Added support for WRITE_VPARMS mailbox command by applications Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c8
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c13
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c34
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c67
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h7
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c22
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c30
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c10
10 files changed, 152 insertions, 41 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index ff6b7d33ccab..636a930a5739 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -367,6 +367,7 @@ struct lpfc_vport {
367 367
368struct hbq_s { 368struct hbq_s {
369 uint16_t entry_count; /* Current number of HBQ slots */ 369 uint16_t entry_count; /* Current number of HBQ slots */
370 uint16_t buffer_count; /* Current number of buffers posted */
370 uint32_t next_hbqPutIdx; /* Index to next HBQ slot to use */ 371 uint32_t next_hbqPutIdx; /* Index to next HBQ slot to use */
371 uint32_t hbqPutIdx; /* HBQ slot to use */ 372 uint32_t hbqPutIdx; /* HBQ slot to use */
372 uint32_t local_hbqGetIdx; /* Local copy of Get index from Port */ 373 uint32_t local_hbqGetIdx; /* Local copy of Get index from Port */
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index e8e9905828c9..4e9e890449a3 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -187,12 +187,9 @@ lpfc_state_show(struct class_device *cdev, char *buf)
187 case LPFC_LINK_UP: 187 case LPFC_LINK_UP:
188 case LPFC_CLEAR_LA: 188 case LPFC_CLEAR_LA:
189 case LPFC_HBA_READY: 189 case LPFC_HBA_READY:
190 len += snprintf(buf + len, PAGE_SIZE-len, "Link Up - \n"); 190 len += snprintf(buf + len, PAGE_SIZE-len, "Link Up - ");
191 191
192 switch (vport->port_state) { 192 switch (vport->port_state) {
193 len += snprintf(buf + len, PAGE_SIZE-len,
194 "initializing\n");
195 break;
196 case LPFC_LOCAL_CFG_LINK: 193 case LPFC_LOCAL_CFG_LINK:
197 len += snprintf(buf + len, PAGE_SIZE-len, 194 len += snprintf(buf + len, PAGE_SIZE-len,
198 "Configuring Link\n"); 195 "Configuring Link\n");
@@ -1759,7 +1756,6 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
1759 1756
1760 switch (phba->sysfs_mbox.mbox->mb.mbxCommand) { 1757 switch (phba->sysfs_mbox.mbox->mb.mbxCommand) {
1761 /* Offline only */ 1758 /* Offline only */
1762 case MBX_WRITE_NV:
1763 case MBX_INIT_LINK: 1759 case MBX_INIT_LINK:
1764 case MBX_DOWN_LINK: 1760 case MBX_DOWN_LINK:
1765 case MBX_CONFIG_LINK: 1761 case MBX_CONFIG_LINK:
@@ -1782,6 +1778,8 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
1782 spin_unlock_irq(&phba->hbalock); 1778 spin_unlock_irq(&phba->hbalock);
1783 return -EPERM; 1779 return -EPERM;
1784 } 1780 }
1781 case MBX_WRITE_NV:
1782 case MBX_WRITE_VPARMS:
1785 case MBX_LOAD_SM: 1783 case MBX_LOAD_SM:
1786 case MBX_READ_NV: 1784 case MBX_READ_NV:
1787 case MBX_READ_CONFIG: 1785 case MBX_READ_CONFIG:
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index d6a98bc970ff..da607c775cfc 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -243,16 +243,17 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
243 raw_index = phba->hbq_get[i]; 243 raw_index = phba->hbq_get[i];
244 getidx = le32_to_cpu(raw_index); 244 getidx = le32_to_cpu(raw_index);
245 len += snprintf(buf+len, size-len, 245 len += snprintf(buf+len, size-len,
246 "entrys:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n", 246 "entrys:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
247 hbqs->entry_count, hbqs->hbqPutIdx, hbqs->next_hbqPutIdx, 247 hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx,
248 hbqs->local_hbqGetIdx, getidx); 248 hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx);
249 249
250 hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt; 250 hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
251 for (j=0; j<hbqs->entry_count; j++) { 251 for (j=0; j<hbqs->entry_count; j++) {
252 len += snprintf(buf+len, size-len, 252 len += snprintf(buf+len, size-len,
253 "%03d: %08x %04x %05x ", j, 253 "%03d: %08x %04x %05x ", j,
254 hbqe->bde.addrLow, hbqe->bde.tus.w, hbqe->buffer_tag); 254 le32_to_cpu(hbqe->bde.addrLow),
255 255 le32_to_cpu(hbqe->bde.tus.w),
256 le32_to_cpu(hbqe->buffer_tag));
256 i = 0; 257 i = 0;
257 found = 0; 258 found = 0;
258 259
@@ -276,7 +277,7 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
276 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) { 277 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
277 hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); 278 hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
278 phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); 279 phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
279 if (phys == hbqe->bde.addrLow) { 280 if (phys == le32_to_cpu(hbqe->bde.addrLow)) {
280 len += snprintf(buf+len, size-len, 281 len += snprintf(buf+len, size-len,
281 "Buf%d: %p %06x\n", i, 282 "Buf%d: %p %06x\n", i,
282 hbq_buf->dbuf.virt, hbq_buf->tag); 283 hbq_buf->dbuf.virt, hbq_buf->tag);
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 99bc1a1ecac2..cfe81c50529a 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -91,6 +91,7 @@ struct lpfc_nodelist {
91#define NLP_LOGO_SND 0x100 /* sent LOGO request for this entry */ 91#define NLP_LOGO_SND 0x100 /* sent LOGO request for this entry */
92#define NLP_RNID_SND 0x400 /* sent RNID request for this entry */ 92#define NLP_RNID_SND 0x400 /* sent RNID request for this entry */
93#define NLP_ELS_SND_MASK 0x7e0 /* sent ELS request for this entry */ 93#define NLP_ELS_SND_MASK 0x7e0 /* sent ELS request for this entry */
94#define NLP_DEFER_RM 0x10000 /* Remove this ndlp if no longer used */
94#define NLP_DELAY_TMO 0x20000 /* delay timeout is running for node */ 95#define NLP_DELAY_TMO 0x20000 /* delay timeout is running for node */
95#define NLP_NPR_2B_DISC 0x40000 /* node is included in num_disc_nodes */ 96#define NLP_NPR_2B_DISC 0x40000 /* node is included in num_disc_nodes */
96#define NLP_RCV_PLOGI 0x80000 /* Rcv'ed PLOGI from remote system */ 97#define NLP_RCV_PLOGI 0x80000 /* Rcv'ed PLOGI from remote system */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 0a5006ea9909..9315c3c2e6f6 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -2069,9 +2069,25 @@ int
2069lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) 2069lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
2070{ 2070{
2071 struct lpfc_dmabuf *buf_ptr, *buf_ptr1; 2071 struct lpfc_dmabuf *buf_ptr, *buf_ptr1;
2072 struct lpfc_nodelist *ndlp;
2072 2073
2073 if (elsiocb->context1) { 2074 ndlp = (struct lpfc_nodelist *)elsiocb->context1;
2074 lpfc_nlp_put(elsiocb->context1); 2075 if (ndlp) {
2076 if (ndlp->nlp_flag & NLP_DEFER_RM) {
2077 lpfc_nlp_put(ndlp);
2078
2079 /* If the ndlp is not being used by another discovery
2080 * thread, free it.
2081 */
2082 if (!lpfc_nlp_not_used(ndlp)) {
2083 /* If ndlp is being used by another discovery
2084 * thread, just clear NLP_DEFER_RM
2085 */
2086 ndlp->nlp_flag &= ~NLP_DEFER_RM;
2087 }
2088 }
2089 else
2090 lpfc_nlp_put(ndlp);
2075 elsiocb->context1 = NULL; 2091 elsiocb->context1 = NULL;
2076 } 2092 }
2077 /* context2 = cmd, context2->next = rsp, context3 = bpl */ 2093 /* context2 = cmd, context2->next = rsp, context3 = bpl */
@@ -2130,13 +2146,15 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2130 lpfc_mbuf_free(phba, mp->virt, mp->phys); 2146 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2131 kfree(mp); 2147 kfree(mp);
2132 mempool_free(pmb, phba->mbox_mem_pool); 2148 mempool_free(pmb, phba->mbox_mem_pool);
2133 lpfc_nlp_put(ndlp); 2149 if (ndlp) {
2150 lpfc_nlp_put(ndlp);
2134 2151
2135 /* This is the end of the default RPI cleanup logic for this 2152 /* This is the end of the default RPI cleanup logic for this
2136 * ndlp. If no other discovery threads are using this ndlp. 2153 * ndlp. If no other discovery threads are using this ndlp.
2137 * we should free all resources associated with it. 2154 * we should free all resources associated with it.
2138 */ 2155 */
2139 lpfc_nlp_not_used(ndlp); 2156 lpfc_nlp_not_used(ndlp);
2157 }
2140 return; 2158 return;
2141} 2159}
2142 2160
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index f64ce88e8a06..371f41e886d6 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -108,6 +108,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
108 struct lpfc_vport *vport; 108 struct lpfc_vport *vport;
109 struct lpfc_hba *phba; 109 struct lpfc_hba *phba;
110 struct lpfc_work_evt *evtp; 110 struct lpfc_work_evt *evtp;
111 int put_node;
112 int put_rport;
111 113
112 rdata = rport->dd_data; 114 rdata = rport->dd_data;
113 ndlp = rdata->pnode; 115 ndlp = rdata->pnode;
@@ -128,6 +130,25 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
128 "rport devlosscb: sid:x%x did:x%x flg:x%x", 130 "rport devlosscb: sid:x%x did:x%x flg:x%x",
129 ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); 131 ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);
130 132
133 /* Don't defer this if we are in the process of deleting the vport
134 * or unloading the driver. The unload will cleanup the node
135 * appropriately we just need to cleanup the ndlp rport info here.
136 */
137 if (vport->load_flag & FC_UNLOADING) {
138 put_node = rdata->pnode != NULL;
139 put_rport = ndlp->rport != NULL;
140 rdata->pnode = NULL;
141 ndlp->rport = NULL;
142 if (put_node)
143 lpfc_nlp_put(ndlp);
144 if (put_rport)
145 put_device(&rport->dev);
146 return;
147 }
148
149 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
150 return;
151
131 evtp = &ndlp->dev_loss_evt; 152 evtp = &ndlp->dev_loss_evt;
132 153
133 if (!list_empty(&evtp->evt_listp)) 154 if (!list_empty(&evtp->evt_listp))
@@ -175,8 +196,23 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
175 "rport devlosstmo:did:x%x type:x%x id:x%x", 196 "rport devlosstmo:did:x%x type:x%x id:x%x",
176 ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id); 197 ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id);
177 198
178 if (!(vport->load_flag & FC_UNLOADING) && 199 /* Don't defer this if we are in the process of deleting the vport
179 ndlp->nlp_state == NLP_STE_MAPPED_NODE) 200 * or unloading the driver. The unload will cleanup the node
201 * appropriately we just need to cleanup the ndlp rport info here.
202 */
203 if (vport->load_flag & FC_UNLOADING) {
204 put_node = rdata->pnode != NULL;
205 put_rport = ndlp->rport != NULL;
206 rdata->pnode = NULL;
207 ndlp->rport = NULL;
208 if (put_node)
209 lpfc_nlp_put(ndlp);
210 if (put_rport)
211 put_device(&rport->dev);
212 return;
213 }
214
215 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
180 return; 216 return;
181 217
182 if (ndlp->nlp_type & NLP_FABRIC) { 218 if (ndlp->nlp_type & NLP_FABRIC) {
@@ -1965,12 +2001,39 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1965static void 2001static void
1966lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) 2002lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1967{ 2003{
2004 struct lpfc_hba *phba = vport->phba;
1968 struct lpfc_rport_data *rdata; 2005 struct lpfc_rport_data *rdata;
2006 LPFC_MBOXQ_t *mbox;
2007 int rc;
1969 2008
1970 if (ndlp->nlp_flag & NLP_DELAY_TMO) { 2009 if (ndlp->nlp_flag & NLP_DELAY_TMO) {
1971 lpfc_cancel_retry_delay_tmo(vport, ndlp); 2010 lpfc_cancel_retry_delay_tmo(vport, ndlp);
1972 } 2011 }
1973 2012
2013 if (ndlp->nlp_flag & NLP_DEFER_RM && !ndlp->nlp_rpi) {
2014 /* For this case we need to cleanup the default rpi
2015 * allocated by the firmware.
2016 */
2017 if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))
2018 != NULL) {
2019 rc = lpfc_reg_login(phba, vport->vpi, ndlp->nlp_DID,
2020 (uint8_t *) &vport->fc_sparam, mbox, 0);
2021 if (rc) {
2022 mempool_free(mbox, phba->mbox_mem_pool);
2023 }
2024 else {
2025 mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
2026 mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
2027 mbox->vport = vport;
2028 mbox->context2 = 0;
2029 rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
2030 if (rc == MBX_NOT_FINISHED) {
2031 mempool_free(mbox, phba->mbox_mem_pool);
2032 }
2033 }
2034 }
2035 }
2036
1974 lpfc_cleanup_node(vport, ndlp); 2037 lpfc_cleanup_node(vport, ndlp);
1975 2038
1976 /* 2039 /*
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index b075d5956488..8635b9294640 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -153,11 +153,7 @@ struct lpfc_sli_ct_request {
153 struct gff_acc { 153 struct gff_acc {
154 uint8_t fbits[128]; 154 uint8_t fbits[128];
155 } gff_acc; 155 } gff_acc;
156#ifdef __BIG_ENDIAN_BITFIELD
157#define FCP_TYPE_FEATURE_OFFSET 7 156#define FCP_TYPE_FEATURE_OFFSET 7
158#else /* __LITTLE_ENDIAN_BITFIELD */
159#define FCP_TYPE_FEATURE_OFFSET 4
160#endif
161 struct rff { 157 struct rff {
162 uint32_t PortId; 158 uint32_t PortId;
163 uint8_t reserved[2]; 159 uint8_t reserved[2];
@@ -1288,8 +1284,9 @@ typedef struct { /* FireFly BIU registers */
1288#define MBX_KILL_BOARD 0x24 1284#define MBX_KILL_BOARD 0x24
1289#define MBX_CONFIG_FARP 0x25 1285#define MBX_CONFIG_FARP 0x25
1290#define MBX_BEACON 0x2A 1286#define MBX_BEACON 0x2A
1291#define MBX_ASYNCEVT_ENABLE 0x33
1292#define MBX_HEARTBEAT 0x31 1287#define MBX_HEARTBEAT 0x31
1288#define MBX_WRITE_VPARMS 0x32
1289#define MBX_ASYNCEVT_ENABLE 0x33
1293 1290
1294#define MBX_CONFIG_HBQ 0x7C 1291#define MBX_CONFIG_HBQ 0x7C
1295#define MBX_LOAD_AREA 0x81 1292#define MBX_LOAD_AREA 0x81
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index ceb185fa3216..db96f7504a14 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1339,6 +1339,7 @@ lpfc_cleanup(struct lpfc_vport *vport)
1339{ 1339{
1340 struct lpfc_hba *phba = vport->phba; 1340 struct lpfc_hba *phba = vport->phba;
1341 struct lpfc_nodelist *ndlp, *next_ndlp; 1341 struct lpfc_nodelist *ndlp, *next_ndlp;
1342 int i = 0;
1342 1343
1343 if (phba->link_state > LPFC_LINK_DOWN) 1344 if (phba->link_state > LPFC_LINK_DOWN)
1344 lpfc_port_link_failure(vport); 1345 lpfc_port_link_failure(vport);
@@ -1351,17 +1352,20 @@ lpfc_cleanup(struct lpfc_vport *vport)
1351 NLP_EVT_DEVICE_RM); 1352 NLP_EVT_DEVICE_RM);
1352 } 1353 }
1353 1354
1354 /* At this point, ALL ndlp's should be gone */ 1355 /* At this point, ALL ndlp's should be gone
1356 * because of the previous NLP_EVT_DEVICE_RM.
1357 * Lets wait for this to happen, if needed.
1358 */
1355 while (!list_empty(&vport->fc_nodes)) { 1359 while (!list_empty(&vport->fc_nodes)) {
1356 1360
1357 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, 1361 if (i++ > 3000) {
1358 nlp_listp) {
1359 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, 1362 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
1360 "0233 Nodelist x%x not free: %d\n", 1363 "0233 Nodelist not empty\n");
1361 ndlp->nlp_DID, 1364 break;
1362 atomic_read(&ndlp->kref.refcount));
1363 lpfc_drop_node(vport, ndlp);
1364 } 1365 }
1366
1367 /* Wait for any activity on ndlps to settle */
1368 msleep(10);
1365 } 1369 }
1366 return; 1370 return;
1367} 1371}
@@ -1499,6 +1503,8 @@ lpfc_offline_prep(struct lpfc_hba * phba)
1499 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { 1503 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
1500 struct Scsi_Host *shost; 1504 struct Scsi_Host *shost;
1501 1505
1506 if (vports[i]->load_flag & FC_UNLOADING)
1507 continue;
1502 shost = lpfc_shost_from_vport(vports[i]); 1508 shost = lpfc_shost_from_vport(vports[i]);
1503 list_for_each_entry_safe(ndlp, next_ndlp, 1509 list_for_each_entry_safe(ndlp, next_ndlp,
1504 &vports[i]->fc_nodes, 1510 &vports[i]->fc_nodes,
@@ -1771,6 +1777,8 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost)
1771 fc_host_supported_speeds(shost) = 0; 1777 fc_host_supported_speeds(shost) = 0;
1772 if (phba->lmt & LMT_10Gb) 1778 if (phba->lmt & LMT_10Gb)
1773 fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT; 1779 fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT;
1780 if (phba->lmt & LMT_8Gb)
1781 fc_host_supported_speeds(shost) |= FC_PORTSPEED_8GBIT;
1774 if (phba->lmt & LMT_4Gb) 1782 if (phba->lmt & LMT_4Gb)
1775 fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT; 1783 fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT;
1776 if (phba->lmt & LMT_2Gb) 1784 if (phba->lmt & LMT_2Gb)
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index bba1fb6103f6..c654c787c3e6 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -287,6 +287,24 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
287 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; 287 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
288 lp = (uint32_t *) pcmd->virt; 288 lp = (uint32_t *) pcmd->virt;
289 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); 289 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
290 if (wwn_to_u64(sp->portName.u.wwn) == 0) {
291 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
292 "0140 PLOGI Reject: invalid nname\n");
293 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
294 stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_PNAME;
295 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
296 NULL);
297 return 0;
298 }
299 if (wwn_to_u64(sp->nodeName.u.wwn) == 0) {
300 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
301 "0141 PLOGI Reject: invalid pname\n");
302 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
303 stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_NNAME;
304 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
305 NULL);
306 return 0;
307 }
290 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3) == 0)) { 308 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3) == 0)) {
291 /* Reject this request because invalid parameters */ 309 /* Reject this request because invalid parameters */
292 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; 310 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
@@ -821,6 +839,12 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
821 839
822 lp = (uint32_t *) prsp->virt; 840 lp = (uint32_t *) prsp->virt;
823 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); 841 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
842 if (wwn_to_u64(sp->portName.u.wwn) == 0 ||
843 wwn_to_u64(sp->nodeName.u.wwn) == 0) {
844 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
845 "0142 PLOGI RSP: Invalid WWN.\n");
846 goto out;
847 }
824 if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3)) 848 if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3))
825 goto out; 849 goto out;
826 /* PLOGI chkparm OK */ 850 /* PLOGI chkparm OK */
@@ -906,9 +930,7 @@ out:
906 "0261 Cannot Register NameServer login\n"); 930 "0261 Cannot Register NameServer login\n");
907 } 931 }
908 932
909 /* Free this node since the driver cannot login or has the wrong 933 ndlp->nlp_flag |= NLP_DEFER_RM;
910 sparm */
911 lpfc_nlp_not_used(ndlp);
912 return NLP_STE_FREED_NODE; 934 return NLP_STE_FREED_NODE;
913} 935}
914 936
@@ -1795,7 +1817,7 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1795 1817
1796 irsp = &rspiocb->iocb; 1818 irsp = &rspiocb->iocb;
1797 if (irsp->ulpStatus) { 1819 if (irsp->ulpStatus) {
1798 lpfc_nlp_not_used(ndlp); 1820 ndlp->nlp_flag |= NLP_DEFER_RM;
1799 return NLP_STE_FREED_NODE; 1821 return NLP_STE_FREED_NODE;
1800 } 1822 }
1801 return ndlp->nlp_state; 1823 return ndlp->nlp_state;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 49f2fdd2ba2b..c3743d6f445b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -540,6 +540,7 @@ lpfc_sli_hbqbuf_free_all(struct lpfc_hba *phba)
540 list_del(&hbq_buf->dbuf.list); 540 list_del(&hbq_buf->dbuf.list);
541 (phba->hbqs[i].hbq_free_buffer)(phba, hbq_buf); 541 (phba->hbqs[i].hbq_free_buffer)(phba, hbq_buf);
542 } 542 }
543 phba->hbqs[i].buffer_count = 0;
543 } 544 }
544} 545}
545 546
@@ -608,8 +609,8 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count)
608 return 0; 609 return 0;
609 } 610 }
610 611
611 start = lpfc_hbq_defs[hbqno]->buffer_count; 612 start = phba->hbqs[hbqno].buffer_count;
612 end = count + lpfc_hbq_defs[hbqno]->buffer_count; 613 end = count + start;
613 if (end > lpfc_hbq_defs[hbqno]->entry_count) { 614 if (end > lpfc_hbq_defs[hbqno]->entry_count) {
614 end = lpfc_hbq_defs[hbqno]->entry_count; 615 end = lpfc_hbq_defs[hbqno]->entry_count;
615 } 616 }
@@ -621,7 +622,7 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count)
621 return 1; 622 return 1;
622 hbq_buffer->tag = (i | (hbqno << 16)); 623 hbq_buffer->tag = (i | (hbqno << 16));
623 if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) 624 if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer))
624 lpfc_hbq_defs[hbqno]->buffer_count++; 625 phba->hbqs[hbqno].buffer_count++;
625 else 626 else
626 (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); 627 (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer);
627 } 628 }
@@ -661,7 +662,7 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag)
661 } 662 }
662 lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT, 663 lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT,
663 "1803 Bad hbq tag. Data: x%x x%x\n", 664 "1803 Bad hbq tag. Data: x%x x%x\n",
664 tag, lpfc_hbq_defs[tag >> 16]->buffer_count); 665 tag, phba->hbqs[tag >> 16].buffer_count);
665 return NULL; 666 return NULL;
666} 667}
667 668
@@ -687,6 +688,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
687 case MBX_LOAD_SM: 688 case MBX_LOAD_SM:
688 case MBX_READ_NV: 689 case MBX_READ_NV:
689 case MBX_WRITE_NV: 690 case MBX_WRITE_NV:
691 case MBX_WRITE_VPARMS:
690 case MBX_RUN_BIU_DIAG: 692 case MBX_RUN_BIU_DIAG:
691 case MBX_INIT_LINK: 693 case MBX_INIT_LINK:
692 case MBX_DOWN_LINK: 694 case MBX_DOWN_LINK: