diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-01-11 01:52:54 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-23 12:29:22 -0500 |
commit | 0937282036d9ae798e02c9c69a8b2ef044048855 (patch) | |
tree | 55c8ef65c9c55e74e8985b58396516b3d3b925ad /drivers/scsi | |
parent | 13815c8344a238c204e4f4339b22dc4833c6df0f (diff) |
[SCSI] lpfc 8.2.4 : Miscellaneous Fixes
Miscellaneous Fixes:
- Fix a couple of sparse complaints
- Reset the FCP recovery flag when the node is not a FCP2 device.
- Speed up offline prep delays
- Fixed a memory leak in lpfc_mem_alloc failure path
- Fixed external loopback test.
- Fixed error code returned from the driver when HBA is over heated.
- Correct Max NPIV vport to limits read from adapter
- Add missing locks around fc_flag and FC_NEEDS_REG_VPI
- Add missing hba ids for device identification
- Added support for SET_VARIABLE and MBX_WRITE_WWN mailbox commands
- Changed all temperature event messages from warning to error
- Fix reporting of link speed when link is down
- Added support for MBX_WRITE_WWN mailbox command
- Change del_timer_sync() in ISR to del_timer() in interrupt handler
- Correct instances of beXX_to_cpu() that should be cpu_to_beXX()
- Perform target flush before releasing node references on module unload
- Avoid bogus devloss_tmo messages when driver unloads
- Fix panic when HBA generates ERATT interupt
- Fix mbox race condition and a workaround on back-to-back mailbox commands
- Force NPIV off for pt2pt mode between 2 NPorts
- Stop worker thread before removing fc_host.
- Fix up discovery timeout error case due to missing clear_la
- Tighten mailbox polling code to speed up detection of fast completions
- Only allow DUMP_MEMORY if adapter offline due to overtemp errors
- Added extended error information to the log messages in chip init.
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.h | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 32 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 16 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 42 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 46 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 119 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mem.c | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 12 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 156 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.h | 2 |
13 files changed, 274 insertions, 169 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 5bf402a20682..2c3e171da8cb 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -559,8 +559,7 @@ struct lpfc_hba { | |||
559 | struct list_head port_list; | 559 | struct list_head port_list; |
560 | struct lpfc_vport *pport; /* physical lpfc_vport pointer */ | 560 | struct lpfc_vport *pport; /* physical lpfc_vport pointer */ |
561 | uint16_t max_vpi; /* Maximum virtual nports */ | 561 | uint16_t max_vpi; /* Maximum virtual nports */ |
562 | #define LPFC_MAX_VPI 100 /* Max number of VPI supported */ | 562 | #define LPFC_MAX_VPI 0xFFFF /* Max number of VPI supported */ |
563 | #define LPFC_MAX_VPORTS (LPFC_MAX_VPI+1)/* Max number of VPorts supported */ | ||
564 | unsigned long *vpi_bmask; /* vpi allocation table */ | 563 | unsigned long *vpi_bmask; /* vpi allocation table */ |
565 | 564 | ||
566 | /* Data structure used by fabric iocb scheduler */ | 565 | /* Data structure used by fabric iocb scheduler */ |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 68e92be1ef5b..eb5a5ad4ffbf 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -311,12 +311,14 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) | |||
311 | 311 | ||
312 | psli = &phba->sli; | 312 | psli = &phba->sli; |
313 | 313 | ||
314 | /* Wait a little for things to settle down, but not | ||
315 | * long enough for dev loss timeout to expire. | ||
316 | */ | ||
314 | for (i = 0; i < psli->num_rings; i++) { | 317 | for (i = 0; i < psli->num_rings; i++) { |
315 | pring = &psli->ring[i]; | 318 | pring = &psli->ring[i]; |
316 | /* The linkdown event takes 30 seconds to timeout. */ | ||
317 | while (pring->txcmplq_cnt) { | 319 | while (pring->txcmplq_cnt) { |
318 | msleep(10); | 320 | msleep(10); |
319 | if (cnt++ > 3000) { | 321 | if (cnt++ > 500) { /* 5 secs */ |
320 | lpfc_printf_log(phba, | 322 | lpfc_printf_log(phba, |
321 | KERN_WARNING, LOG_INIT, | 323 | KERN_WARNING, LOG_INIT, |
322 | "0466 Outstanding IO when " | 324 | "0466 Outstanding IO when " |
@@ -989,7 +991,7 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) | |||
989 | spin_lock_irq(&phba->hbalock); | 991 | spin_lock_irq(&phba->hbalock); |
990 | if (phba->over_temp_state == HBA_OVER_TEMP) { | 992 | if (phba->over_temp_state == HBA_OVER_TEMP) { |
991 | spin_unlock_irq(&phba->hbalock); | 993 | spin_unlock_irq(&phba->hbalock); |
992 | return -EPERM; | 994 | return -EACCES; |
993 | } | 995 | } |
994 | spin_unlock_irq(&phba->hbalock); | 996 | spin_unlock_irq(&phba->hbalock); |
995 | /* count may include a LF at end of string */ | 997 | /* count may include a LF at end of string */ |
@@ -1782,7 +1784,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1782 | if (phba->over_temp_state == HBA_OVER_TEMP) { | 1784 | if (phba->over_temp_state == HBA_OVER_TEMP) { |
1783 | sysfs_mbox_idle(phba); | 1785 | sysfs_mbox_idle(phba); |
1784 | spin_unlock_irq(&phba->hbalock); | 1786 | spin_unlock_irq(&phba->hbalock); |
1785 | return -EPERM; | 1787 | return -EACCES; |
1786 | } | 1788 | } |
1787 | 1789 | ||
1788 | if (off == 0 && | 1790 | if (off == 0 && |
@@ -1801,9 +1803,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1801 | case MBX_DUMP_CONTEXT: | 1803 | case MBX_DUMP_CONTEXT: |
1802 | case MBX_RUN_DIAGS: | 1804 | case MBX_RUN_DIAGS: |
1803 | case MBX_RESTART: | 1805 | case MBX_RESTART: |
1804 | case MBX_FLASH_WR_ULA: | ||
1805 | case MBX_SET_MASK: | 1806 | case MBX_SET_MASK: |
1806 | case MBX_SET_SLIM: | ||
1807 | case MBX_SET_DEBUG: | 1807 | case MBX_SET_DEBUG: |
1808 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) { | 1808 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) { |
1809 | printk(KERN_WARNING "mbox_read:Command 0x%x " | 1809 | printk(KERN_WARNING "mbox_read:Command 0x%x " |
@@ -1831,6 +1831,8 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1831 | case MBX_LOAD_EXP_ROM: | 1831 | case MBX_LOAD_EXP_ROM: |
1832 | case MBX_BEACON: | 1832 | case MBX_BEACON: |
1833 | case MBX_DEL_LD_ENTRY: | 1833 | case MBX_DEL_LD_ENTRY: |
1834 | case MBX_SET_VARIABLE: | ||
1835 | case MBX_WRITE_WWN: | ||
1834 | break; | 1836 | break; |
1835 | case MBX_READ_SPARM64: | 1837 | case MBX_READ_SPARM64: |
1836 | case MBX_READ_LA: | 1838 | case MBX_READ_LA: |
@@ -1852,6 +1854,17 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1852 | return -EPERM; | 1854 | return -EPERM; |
1853 | } | 1855 | } |
1854 | 1856 | ||
1857 | /* If HBA encountered an error attention, allow only DUMP | ||
1858 | * mailbox command until the HBA is restarted. | ||
1859 | */ | ||
1860 | if ((phba->pport->stopped) && | ||
1861 | (phba->sysfs_mbox.mbox->mb.mbxCommand | ||
1862 | != MBX_DUMP_MEMORY)) { | ||
1863 | sysfs_mbox_idle(phba); | ||
1864 | spin_unlock_irq(&phba->hbalock); | ||
1865 | return -EPERM; | ||
1866 | } | ||
1867 | |||
1855 | phba->sysfs_mbox.mbox->vport = vport; | 1868 | phba->sysfs_mbox.mbox->vport = vport; |
1856 | 1869 | ||
1857 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { | 1870 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { |
@@ -2052,7 +2065,8 @@ lpfc_get_host_speed(struct Scsi_Host *shost) | |||
2052 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; | 2065 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; |
2053 | break; | 2066 | break; |
2054 | } | 2067 | } |
2055 | } | 2068 | } else |
2069 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; | ||
2056 | 2070 | ||
2057 | spin_unlock_irq(shost->host_lock); | 2071 | spin_unlock_irq(shost->host_lock); |
2058 | } | 2072 | } |
@@ -2072,7 +2086,7 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost) | |||
2072 | node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn); | 2086 | node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn); |
2073 | else | 2087 | else |
2074 | /* fabric is local port if there is no F/FL_Port */ | 2088 | /* fabric is local port if there is no F/FL_Port */ |
2075 | node_name = wwn_to_u64(vport->fc_nodename.u.wwn); | 2089 | node_name = 0; |
2076 | 2090 | ||
2077 | spin_unlock_irq(shost->host_lock); | 2091 | spin_unlock_irq(shost->host_lock); |
2078 | 2092 | ||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index c735ed4ad070..7a8b3b90af71 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -19,7 +19,7 @@ | |||
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Fibre Channel SCSI LAN Device Driver CT support | 22 | * Fibre Channel SCSI LAN Device Driver CT support: FC Generic Services FC-GS |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/blkdev.h> | 25 | #include <linux/blkdev.h> |
@@ -203,7 +203,7 @@ lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl, | |||
203 | struct lpfc_dmabuf *mp; | 203 | struct lpfc_dmabuf *mp; |
204 | int cnt, i = 0; | 204 | int cnt, i = 0; |
205 | 205 | ||
206 | /* We get chucks of FCELSSIZE */ | 206 | /* We get chunks of FCELSSIZE */ |
207 | cnt = size > FCELSSIZE ? FCELSSIZE: size; | 207 | cnt = size > FCELSSIZE ? FCELSSIZE: size; |
208 | 208 | ||
209 | while (size) { | 209 | while (size) { |
@@ -1175,7 +1175,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1175 | case SLI_CTNS_GFF_ID: | 1175 | case SLI_CTNS_GFF_ID: |
1176 | CtReq->CommandResponse.bits.CmdRsp = | 1176 | CtReq->CommandResponse.bits.CmdRsp = |
1177 | be16_to_cpu(SLI_CTNS_GFF_ID); | 1177 | be16_to_cpu(SLI_CTNS_GFF_ID); |
1178 | CtReq->un.gff.PortId = be32_to_cpu(context); | 1178 | CtReq->un.gff.PortId = cpu_to_be32(context); |
1179 | cmpl = lpfc_cmpl_ct_cmd_gff_id; | 1179 | cmpl = lpfc_cmpl_ct_cmd_gff_id; |
1180 | break; | 1180 | break; |
1181 | 1181 | ||
@@ -1183,7 +1183,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1183 | vport->ct_flags &= ~FC_CT_RFT_ID; | 1183 | vport->ct_flags &= ~FC_CT_RFT_ID; |
1184 | CtReq->CommandResponse.bits.CmdRsp = | 1184 | CtReq->CommandResponse.bits.CmdRsp = |
1185 | be16_to_cpu(SLI_CTNS_RFT_ID); | 1185 | be16_to_cpu(SLI_CTNS_RFT_ID); |
1186 | CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID); | 1186 | CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID); |
1187 | CtReq->un.rft.fcpReg = 1; | 1187 | CtReq->un.rft.fcpReg = 1; |
1188 | cmpl = lpfc_cmpl_ct_cmd_rft_id; | 1188 | cmpl = lpfc_cmpl_ct_cmd_rft_id; |
1189 | break; | 1189 | break; |
@@ -1192,7 +1192,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1192 | vport->ct_flags &= ~FC_CT_RNN_ID; | 1192 | vport->ct_flags &= ~FC_CT_RNN_ID; |
1193 | CtReq->CommandResponse.bits.CmdRsp = | 1193 | CtReq->CommandResponse.bits.CmdRsp = |
1194 | be16_to_cpu(SLI_CTNS_RNN_ID); | 1194 | be16_to_cpu(SLI_CTNS_RNN_ID); |
1195 | CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID); | 1195 | CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID); |
1196 | memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, | 1196 | memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, |
1197 | sizeof (struct lpfc_name)); | 1197 | sizeof (struct lpfc_name)); |
1198 | cmpl = lpfc_cmpl_ct_cmd_rnn_id; | 1198 | cmpl = lpfc_cmpl_ct_cmd_rnn_id; |
@@ -1202,7 +1202,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1202 | vport->ct_flags &= ~FC_CT_RSPN_ID; | 1202 | vport->ct_flags &= ~FC_CT_RSPN_ID; |
1203 | CtReq->CommandResponse.bits.CmdRsp = | 1203 | CtReq->CommandResponse.bits.CmdRsp = |
1204 | be16_to_cpu(SLI_CTNS_RSPN_ID); | 1204 | be16_to_cpu(SLI_CTNS_RSPN_ID); |
1205 | CtReq->un.rspn.PortId = be32_to_cpu(vport->fc_myDID); | 1205 | CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID); |
1206 | size = sizeof(CtReq->un.rspn.symbname); | 1206 | size = sizeof(CtReq->un.rspn.symbname); |
1207 | CtReq->un.rspn.len = | 1207 | CtReq->un.rspn.len = |
1208 | lpfc_vport_symbolic_port_name(vport, | 1208 | lpfc_vport_symbolic_port_name(vport, |
@@ -1225,14 +1225,14 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1225 | /* Implement DA_ID Nameserver request */ | 1225 | /* Implement DA_ID Nameserver request */ |
1226 | CtReq->CommandResponse.bits.CmdRsp = | 1226 | CtReq->CommandResponse.bits.CmdRsp = |
1227 | be16_to_cpu(SLI_CTNS_DA_ID); | 1227 | be16_to_cpu(SLI_CTNS_DA_ID); |
1228 | CtReq->un.da_id.port_id = be32_to_cpu(vport->fc_myDID); | 1228 | CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID); |
1229 | cmpl = lpfc_cmpl_ct_cmd_da_id; | 1229 | cmpl = lpfc_cmpl_ct_cmd_da_id; |
1230 | break; | 1230 | break; |
1231 | case SLI_CTNS_RFF_ID: | 1231 | case SLI_CTNS_RFF_ID: |
1232 | vport->ct_flags &= ~FC_CT_RFF_ID; | 1232 | vport->ct_flags &= ~FC_CT_RFF_ID; |
1233 | CtReq->CommandResponse.bits.CmdRsp = | 1233 | CtReq->CommandResponse.bits.CmdRsp = |
1234 | be16_to_cpu(SLI_CTNS_RFF_ID); | 1234 | be16_to_cpu(SLI_CTNS_RFF_ID); |
1235 | CtReq->un.rff.PortId = be32_to_cpu(vport->fc_myDID);; | 1235 | CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);; |
1236 | CtReq->un.rff.fbits = FC4_FEATURE_INIT; | 1236 | CtReq->un.rff.fbits = FC4_FEATURE_INIT; |
1237 | CtReq->un.rff.type_code = FC_FCP_DATA; | 1237 | CtReq->un.rff.type_code = FC_FCP_DATA; |
1238 | cmpl = lpfc_cmpl_ct_cmd_rff_id; | 1238 | cmpl = lpfc_cmpl_ct_cmd_rff_id; |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index f5e002435972..8da6e8be9d83 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * more details, a copy of which can be found in the file COPYING * | 18 | * more details, a copy of which can be found in the file COPYING * |
19 | * included with this package. * | 19 | * included with this package. * |
20 | *******************************************************************/ | 20 | *******************************************************************/ |
21 | 21 | /* See Fibre Channel protocol T11 FC-LS for details */ | |
22 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
@@ -392,11 +392,12 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
392 | } | 392 | } |
393 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { | 393 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { |
394 | lpfc_mbx_unreg_vpi(vport); | 394 | lpfc_mbx_unreg_vpi(vport); |
395 | spin_lock_irq(shost->host_lock); | ||
395 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 396 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
397 | spin_unlock_irq(shost->host_lock); | ||
396 | } | 398 | } |
397 | } | 399 | } |
398 | 400 | ||
399 | ndlp->nlp_sid = irsp->un.ulpWord[4] & Mask_DID; | ||
400 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); | 401 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); |
401 | 402 | ||
402 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED && | 403 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED && |
@@ -484,6 +485,9 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
484 | lpfc_nlp_put(ndlp); | 485 | lpfc_nlp_put(ndlp); |
485 | } | 486 | } |
486 | 487 | ||
488 | /* If we are pt2pt with another NPort, force NPIV off! */ | ||
489 | phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; | ||
490 | |||
487 | spin_lock_irq(shost->host_lock); | 491 | spin_lock_irq(shost->host_lock); |
488 | vport->fc_flag |= FC_PT2PT; | 492 | vport->fc_flag |= FC_PT2PT; |
489 | spin_unlock_irq(shost->host_lock); | 493 | spin_unlock_irq(shost->host_lock); |
@@ -2068,7 +2072,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2068 | return 0; | 2072 | return 0; |
2069 | } | 2073 | } |
2070 | 2074 | ||
2071 | int | 2075 | static int |
2072 | lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1) | 2076 | lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1) |
2073 | { | 2077 | { |
2074 | struct lpfc_dmabuf *buf_ptr; | 2078 | struct lpfc_dmabuf *buf_ptr; |
@@ -2086,7 +2090,7 @@ lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1) | |||
2086 | return 0; | 2090 | return 0; |
2087 | } | 2091 | } |
2088 | 2092 | ||
2089 | int | 2093 | static int |
2090 | lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr) | 2094 | lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr) |
2091 | { | 2095 | { |
2092 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | 2096 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); |
@@ -2976,10 +2980,10 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2976 | "RCV RSCN defer: did:x%x/ste:x%x flg:x%x", | 2980 | "RCV RSCN defer: did:x%x/ste:x%x flg:x%x", |
2977 | ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); | 2981 | ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); |
2978 | 2982 | ||
2983 | spin_lock_irq(shost->host_lock); | ||
2979 | vport->fc_flag |= FC_RSCN_DEFERRED; | 2984 | vport->fc_flag |= FC_RSCN_DEFERRED; |
2980 | if ((rscn_cnt < FC_MAX_HOLD_RSCN) && | 2985 | if ((rscn_cnt < FC_MAX_HOLD_RSCN) && |
2981 | !(vport->fc_flag & FC_RSCN_DISCOVERY)) { | 2986 | !(vport->fc_flag & FC_RSCN_DISCOVERY)) { |
2982 | spin_lock_irq(shost->host_lock); | ||
2983 | vport->fc_flag |= FC_RSCN_MODE; | 2987 | vport->fc_flag |= FC_RSCN_MODE; |
2984 | spin_unlock_irq(shost->host_lock); | 2988 | spin_unlock_irq(shost->host_lock); |
2985 | if (rscn_cnt) { | 2989 | if (rscn_cnt) { |
@@ -3008,7 +3012,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3008 | vport->fc_rscn_id_cnt, vport->fc_flag, | 3012 | vport->fc_rscn_id_cnt, vport->fc_flag, |
3009 | vport->port_state); | 3013 | vport->port_state); |
3010 | } else { | 3014 | } else { |
3011 | spin_lock_irq(shost->host_lock); | ||
3012 | vport->fc_flag |= FC_RSCN_DISCOVERY; | 3015 | vport->fc_flag |= FC_RSCN_DISCOVERY; |
3013 | spin_unlock_irq(shost->host_lock); | 3016 | spin_unlock_irq(shost->host_lock); |
3014 | /* ReDiscovery RSCN */ | 3017 | /* ReDiscovery RSCN */ |
@@ -3023,7 +3026,9 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3023 | 3026 | ||
3024 | /* send RECOVERY event for ALL nodes that match RSCN payload */ | 3027 | /* send RECOVERY event for ALL nodes that match RSCN payload */ |
3025 | lpfc_rscn_recovery_check(vport); | 3028 | lpfc_rscn_recovery_check(vport); |
3029 | spin_lock_irq(shost->host_lock); | ||
3026 | vport->fc_flag &= ~FC_RSCN_DEFERRED; | 3030 | vport->fc_flag &= ~FC_RSCN_DEFERRED; |
3031 | spin_unlock_irq(shost->host_lock); | ||
3027 | return 0; | 3032 | return 0; |
3028 | } | 3033 | } |
3029 | 3034 | ||
@@ -3307,13 +3312,13 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3307 | status |= 0x4; | 3312 | status |= 0x4; |
3308 | 3313 | ||
3309 | rps_rsp->rsvd1 = 0; | 3314 | rps_rsp->rsvd1 = 0; |
3310 | rps_rsp->portStatus = be16_to_cpu(status); | 3315 | rps_rsp->portStatus = cpu_to_be16(status); |
3311 | rps_rsp->linkFailureCnt = be32_to_cpu(mb->un.varRdLnk.linkFailureCnt); | 3316 | rps_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt); |
3312 | rps_rsp->lossSyncCnt = be32_to_cpu(mb->un.varRdLnk.lossSyncCnt); | 3317 | rps_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt); |
3313 | rps_rsp->lossSignalCnt = be32_to_cpu(mb->un.varRdLnk.lossSignalCnt); | 3318 | rps_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt); |
3314 | rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt); | 3319 | rps_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt); |
3315 | rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord); | 3320 | rps_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord); |
3316 | rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt); | 3321 | rps_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt); |
3317 | /* Xmit ELS RPS ACC response tag <ulpIoTag> */ | 3322 | /* Xmit ELS RPS ACC response tag <ulpIoTag> */ |
3318 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS, | 3323 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS, |
3319 | "0118 Xmit ELS RPS ACC response tag x%x xri x%x, " | 3324 | "0118 Xmit ELS RPS ACC response tag x%x xri x%x, " |
@@ -4276,7 +4281,9 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4276 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; | 4281 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
4277 | MAILBOX_t *mb = &pmb->mb; | 4282 | MAILBOX_t *mb = &pmb->mb; |
4278 | 4283 | ||
4284 | spin_lock_irq(shost->host_lock); | ||
4279 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | 4285 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; |
4286 | spin_unlock_irq(shost->host_lock); | ||
4280 | lpfc_nlp_put(ndlp); | 4287 | lpfc_nlp_put(ndlp); |
4281 | 4288 | ||
4282 | if (mb->mbxStatus) { | 4289 | if (mb->mbxStatus) { |
@@ -4297,7 +4304,9 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4297 | default: | 4304 | default: |
4298 | /* Try to recover from this error */ | 4305 | /* Try to recover from this error */ |
4299 | lpfc_mbx_unreg_vpi(vport); | 4306 | lpfc_mbx_unreg_vpi(vport); |
4307 | spin_lock_irq(shost->host_lock); | ||
4300 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 4308 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
4309 | spin_unlock_irq(shost->host_lock); | ||
4301 | lpfc_initial_fdisc(vport); | 4310 | lpfc_initial_fdisc(vport); |
4302 | break; | 4311 | break; |
4303 | } | 4312 | } |
@@ -4316,6 +4325,7 @@ static void | |||
4316 | lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, | 4325 | lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, |
4317 | struct lpfc_nodelist *ndlp) | 4326 | struct lpfc_nodelist *ndlp) |
4318 | { | 4327 | { |
4328 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
4319 | LPFC_MBOXQ_t *mbox; | 4329 | LPFC_MBOXQ_t *mbox; |
4320 | 4330 | ||
4321 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4331 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
@@ -4327,7 +4337,9 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, | |||
4327 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) | 4337 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) |
4328 | == MBX_NOT_FINISHED) { | 4338 | == MBX_NOT_FINISHED) { |
4329 | mempool_free(mbox, phba->mbox_mem_pool); | 4339 | mempool_free(mbox, phba->mbox_mem_pool); |
4340 | spin_lock_irq(shost->host_lock); | ||
4330 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | 4341 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; |
4342 | spin_unlock_irq(shost->host_lock); | ||
4331 | 4343 | ||
4332 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 4344 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
4333 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 4345 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
@@ -4339,7 +4351,9 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, | |||
4339 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 4351 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
4340 | "0254 Register VPI: no memory\n"); | 4352 | "0254 Register VPI: no memory\n"); |
4341 | 4353 | ||
4354 | spin_lock_irq(shost->host_lock); | ||
4342 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | 4355 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; |
4356 | spin_unlock_irq(shost->host_lock); | ||
4343 | lpfc_nlp_put(ndlp); | 4357 | lpfc_nlp_put(ndlp); |
4344 | } | 4358 | } |
4345 | } | 4359 | } |
@@ -4412,7 +4426,9 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4412 | lpfc_unreg_rpi(vport, np); | 4426 | lpfc_unreg_rpi(vport, np); |
4413 | } | 4427 | } |
4414 | lpfc_mbx_unreg_vpi(vport); | 4428 | lpfc_mbx_unreg_vpi(vport); |
4429 | spin_lock_irq(shost->host_lock); | ||
4415 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 4430 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
4431 | spin_unlock_irq(shost->host_lock); | ||
4416 | } | 4432 | } |
4417 | 4433 | ||
4418 | if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) | 4434 | if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f2b8bc49fe52..644d96012d56 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -114,15 +114,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
114 | 114 | ||
115 | rdata = rport->dd_data; | 115 | rdata = rport->dd_data; |
116 | ndlp = rdata->pnode; | 116 | ndlp = rdata->pnode; |
117 | 117 | if (!ndlp) | |
118 | if (!ndlp) { | ||
119 | if (rport->scsi_target_id != -1) { | ||
120 | printk(KERN_ERR "Cannot find remote node" | ||
121 | " for rport in dev_loss_tmo_callbk x%x\n", | ||
122 | rport->port_id); | ||
123 | } | ||
124 | return; | 118 | return; |
125 | } | ||
126 | 119 | ||
127 | vport = ndlp->vport; | 120 | vport = ndlp->vport; |
128 | phba = vport->phba; | 121 | phba = vport->phba; |
@@ -202,6 +195,12 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
202 | * appropriately we just need to cleanup the ndlp rport info here. | 195 | * appropriately we just need to cleanup the ndlp rport info here. |
203 | */ | 196 | */ |
204 | if (vport->load_flag & FC_UNLOADING) { | 197 | if (vport->load_flag & FC_UNLOADING) { |
198 | if (ndlp->nlp_sid != NLP_NO_SID) { | ||
199 | /* flush the target */ | ||
200 | lpfc_sli_abort_iocb(vport, | ||
201 | &phba->sli.ring[phba->sli.fcp_ring], | ||
202 | ndlp->nlp_sid, 0, LPFC_CTX_TGT); | ||
203 | } | ||
205 | put_node = rdata->pnode != NULL; | 204 | put_node = rdata->pnode != NULL; |
206 | put_rport = ndlp->rport != NULL; | 205 | put_rport = ndlp->rport != NULL; |
207 | rdata->pnode = NULL; | 206 | rdata->pnode = NULL; |
@@ -381,7 +380,7 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
381 | lpfc_handle_latt(phba); | 380 | lpfc_handle_latt(phba); |
382 | vports = lpfc_create_vport_work_array(phba); | 381 | vports = lpfc_create_vport_work_array(phba); |
383 | if (vports != NULL) | 382 | if (vports != NULL) |
384 | for(i = 0; i < LPFC_MAX_VPORTS; i++) { | 383 | for(i = 0; i <= phba->max_vpi; i++) { |
385 | /* | 384 | /* |
386 | * We could have no vports in array if unloading, so if | 385 | * We could have no vports in array if unloading, so if |
387 | * this happens then just use the pport | 386 | * this happens then just use the pport |
@@ -413,7 +412,7 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
413 | vport->work_port_events &= ~work_port_events; | 412 | vport->work_port_events &= ~work_port_events; |
414 | spin_unlock_irq(&vport->work_port_lock); | 413 | spin_unlock_irq(&vport->work_port_lock); |
415 | } | 414 | } |
416 | lpfc_destroy_vport_work_array(vports); | 415 | lpfc_destroy_vport_work_array(phba, vports); |
417 | 416 | ||
418 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 417 | pring = &phba->sli.ring[LPFC_ELS_RING]; |
419 | status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING))); | 418 | status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING))); |
@@ -552,6 +551,7 @@ lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2, | |||
552 | void | 551 | void |
553 | lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) | 552 | lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) |
554 | { | 553 | { |
554 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
555 | struct lpfc_hba *phba = vport->phba; | 555 | struct lpfc_hba *phba = vport->phba; |
556 | struct lpfc_nodelist *ndlp, *next_ndlp; | 556 | struct lpfc_nodelist *ndlp, *next_ndlp; |
557 | int rc; | 557 | int rc; |
@@ -575,7 +575,9 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) | |||
575 | } | 575 | } |
576 | if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) { | 576 | if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) { |
577 | lpfc_mbx_unreg_vpi(vport); | 577 | lpfc_mbx_unreg_vpi(vport); |
578 | spin_lock_irq(shost->host_lock); | ||
578 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 579 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
580 | spin_unlock_irq(shost->host_lock); | ||
579 | } | 581 | } |
580 | } | 582 | } |
581 | 583 | ||
@@ -629,11 +631,11 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
629 | spin_unlock_irq(&phba->hbalock); | 631 | spin_unlock_irq(&phba->hbalock); |
630 | vports = lpfc_create_vport_work_array(phba); | 632 | vports = lpfc_create_vport_work_array(phba); |
631 | if (vports != NULL) | 633 | if (vports != NULL) |
632 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 634 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
633 | /* Issue a LINK DOWN event to all nodes */ | 635 | /* Issue a LINK DOWN event to all nodes */ |
634 | lpfc_linkdown_port(vports[i]); | 636 | lpfc_linkdown_port(vports[i]); |
635 | } | 637 | } |
636 | lpfc_destroy_vport_work_array(vports); | 638 | lpfc_destroy_vport_work_array(phba, vports); |
637 | /* Clean up any firmware default rpi's */ | 639 | /* Clean up any firmware default rpi's */ |
638 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 640 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
639 | if (mb) { | 641 | if (mb) { |
@@ -738,9 +740,9 @@ lpfc_linkup(struct lpfc_hba *phba) | |||
738 | 740 | ||
739 | vports = lpfc_create_vport_work_array(phba); | 741 | vports = lpfc_create_vport_work_array(phba); |
740 | if (vports != NULL) | 742 | if (vports != NULL) |
741 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) | 743 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) |
742 | lpfc_linkup_port(vports[i]); | 744 | lpfc_linkup_port(vports[i]); |
743 | lpfc_destroy_vport_work_array(vports); | 745 | lpfc_destroy_vport_work_array(phba, vports); |
744 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | 746 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) |
745 | lpfc_issue_clear_la(phba, phba->pport); | 747 | lpfc_issue_clear_la(phba, phba->pport); |
746 | 748 | ||
@@ -1319,7 +1321,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1319 | vports = lpfc_create_vport_work_array(phba); | 1321 | vports = lpfc_create_vport_work_array(phba); |
1320 | if (vports != NULL) | 1322 | if (vports != NULL) |
1321 | for(i = 0; | 1323 | for(i = 0; |
1322 | i < LPFC_MAX_VPORTS && vports[i] != NULL; | 1324 | i <= phba->max_vpi && vports[i] != NULL; |
1323 | i++) { | 1325 | i++) { |
1324 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | 1326 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) |
1325 | continue; | 1327 | continue; |
@@ -1335,7 +1337,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1335 | "Fabric support\n"); | 1337 | "Fabric support\n"); |
1336 | } | 1338 | } |
1337 | } | 1339 | } |
1338 | lpfc_destroy_vport_work_array(vports); | 1340 | lpfc_destroy_vport_work_array(phba, vports); |
1339 | lpfc_do_scr_ns_plogi(phba, vport); | 1341 | lpfc_do_scr_ns_plogi(phba, vport); |
1340 | } | 1342 | } |
1341 | 1343 | ||
@@ -1902,7 +1904,8 @@ lpfc_unreg_all_rpis(struct lpfc_vport *vport) | |||
1902 | lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox); | 1904 | lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox); |
1903 | mbox->vport = vport; | 1905 | mbox->vport = vport; |
1904 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1906 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
1905 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 1907 | mbox->context1 = NULL; |
1908 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); | ||
1906 | if (rc == MBX_NOT_FINISHED) { | 1909 | if (rc == MBX_NOT_FINISHED) { |
1907 | mempool_free(mbox, phba->mbox_mem_pool); | 1910 | mempool_free(mbox, phba->mbox_mem_pool); |
1908 | } | 1911 | } |
@@ -1921,7 +1924,8 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport) | |||
1921 | lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox); | 1924 | lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox); |
1922 | mbox->vport = vport; | 1925 | mbox->vport = vport; |
1923 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1926 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
1924 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 1927 | mbox->context1 = NULL; |
1928 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); | ||
1925 | if (rc == MBX_NOT_FINISHED) { | 1929 | if (rc == MBX_NOT_FINISHED) { |
1926 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, | 1930 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, |
1927 | "1815 Could not issue " | 1931 | "1815 Could not issue " |
@@ -2026,7 +2030,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2026 | mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; | 2030 | mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; |
2027 | mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | 2031 | mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; |
2028 | mbox->vport = vport; | 2032 | mbox->vport = vport; |
2029 | mbox->context2 = 0; | 2033 | mbox->context2 = NULL; |
2030 | rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 2034 | rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
2031 | if (rc == MBX_NOT_FINISHED) { | 2035 | if (rc == MBX_NOT_FINISHED) { |
2032 | mempool_free(mbox, phba->mbox_mem_pool); | 2036 | mempool_free(mbox, phba->mbox_mem_pool); |
@@ -2702,12 +2706,14 @@ restart_disc: | |||
2702 | clrlaerr = 1; | 2706 | clrlaerr = 1; |
2703 | break; | 2707 | break; |
2704 | 2708 | ||
2709 | case LPFC_LINK_UP: | ||
2710 | lpfc_issue_clear_la(phba, vport); | ||
2711 | /* Drop thru */ | ||
2705 | case LPFC_LINK_UNKNOWN: | 2712 | case LPFC_LINK_UNKNOWN: |
2706 | case LPFC_WARM_START: | 2713 | case LPFC_WARM_START: |
2707 | case LPFC_INIT_START: | 2714 | case LPFC_INIT_START: |
2708 | case LPFC_INIT_MBX_CMDS: | 2715 | case LPFC_INIT_MBX_CMDS: |
2709 | case LPFC_LINK_DOWN: | 2716 | case LPFC_LINK_DOWN: |
2710 | case LPFC_LINK_UP: | ||
2711 | case LPFC_HBA_ERROR: | 2717 | case LPFC_HBA_ERROR: |
2712 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 2718 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
2713 | "0230 Unexpected timeout, hba link " | 2719 | "0230 Unexpected timeout, hba link " |
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index b61e45a1310d..f78d23a3b667 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -1279,7 +1279,7 @@ typedef struct { /* FireFly BIU registers */ | |||
1279 | #define MBX_DEL_LD_ENTRY 0x1D | 1279 | #define MBX_DEL_LD_ENTRY 0x1D |
1280 | #define MBX_RUN_PROGRAM 0x1E | 1280 | #define MBX_RUN_PROGRAM 0x1E |
1281 | #define MBX_SET_MASK 0x20 | 1281 | #define MBX_SET_MASK 0x20 |
1282 | #define MBX_SET_SLIM 0x21 | 1282 | #define MBX_SET_VARIABLE 0x21 |
1283 | #define MBX_UNREG_D_ID 0x23 | 1283 | #define MBX_UNREG_D_ID 0x23 |
1284 | #define MBX_KILL_BOARD 0x24 | 1284 | #define MBX_KILL_BOARD 0x24 |
1285 | #define MBX_CONFIG_FARP 0x25 | 1285 | #define MBX_CONFIG_FARP 0x25 |
@@ -1301,7 +1301,7 @@ typedef struct { /* FireFly BIU registers */ | |||
1301 | #define MBX_REG_VNPID 0x96 | 1301 | #define MBX_REG_VNPID 0x96 |
1302 | #define MBX_UNREG_VNPID 0x97 | 1302 | #define MBX_UNREG_VNPID 0x97 |
1303 | 1303 | ||
1304 | #define MBX_FLASH_WR_ULA 0x98 | 1304 | #define MBX_WRITE_WWN 0x98 |
1305 | #define MBX_SET_DEBUG 0x99 | 1305 | #define MBX_SET_DEBUG 0x99 |
1306 | #define MBX_LOAD_EXP_ROM 0x9C | 1306 | #define MBX_LOAD_EXP_ROM 0x9C |
1307 | 1307 | ||
@@ -3227,6 +3227,8 @@ lpfc_is_LC_HBA(unsigned short device) | |||
3227 | (device == PCI_DEVICE_ID_BSMB) || | 3227 | (device == PCI_DEVICE_ID_BSMB) || |
3228 | (device == PCI_DEVICE_ID_ZMID) || | 3228 | (device == PCI_DEVICE_ID_ZMID) || |
3229 | (device == PCI_DEVICE_ID_ZSMB) || | 3229 | (device == PCI_DEVICE_ID_ZSMB) || |
3230 | (device == PCI_DEVICE_ID_SAT_MID) || | ||
3231 | (device == PCI_DEVICE_ID_SAT_SMB) || | ||
3230 | (device == PCI_DEVICE_ID_RFLY)) | 3232 | (device == PCI_DEVICE_ID_RFLY)) |
3231 | return 1; | 3233 | return 1; |
3232 | else | 3234 | else |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index c6b30a8617bc..e17bb900aad1 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -484,6 +484,9 @@ lpfc_hba_down_post(struct lpfc_hba *phba) | |||
484 | struct lpfc_sli *psli = &phba->sli; | 484 | struct lpfc_sli *psli = &phba->sli; |
485 | struct lpfc_sli_ring *pring; | 485 | struct lpfc_sli_ring *pring; |
486 | struct lpfc_dmabuf *mp, *next_mp; | 486 | struct lpfc_dmabuf *mp, *next_mp; |
487 | struct lpfc_iocbq *iocb; | ||
488 | IOCB_t *cmd = NULL; | ||
489 | LIST_HEAD(completions); | ||
487 | int i; | 490 | int i; |
488 | 491 | ||
489 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) | 492 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) |
@@ -499,10 +502,36 @@ lpfc_hba_down_post(struct lpfc_hba *phba) | |||
499 | } | 502 | } |
500 | } | 503 | } |
501 | 504 | ||
505 | spin_lock_irq(&phba->hbalock); | ||
502 | for (i = 0; i < psli->num_rings; i++) { | 506 | for (i = 0; i < psli->num_rings; i++) { |
503 | pring = &psli->ring[i]; | 507 | pring = &psli->ring[i]; |
508 | |||
509 | /* At this point in time the HBA is either reset or DOA. Either | ||
510 | * way, nothing should be on txcmplq as it will NEVER complete. | ||
511 | */ | ||
512 | list_splice_init(&pring->txcmplq, &completions); | ||
513 | pring->txcmplq_cnt = 0; | ||
514 | spin_unlock_irq(&phba->hbalock); | ||
515 | |||
516 | while (!list_empty(&completions)) { | ||
517 | iocb = list_get_first(&completions, struct lpfc_iocbq, | ||
518 | list); | ||
519 | cmd = &iocb->iocb; | ||
520 | list_del_init(&iocb->list); | ||
521 | |||
522 | if (!iocb->iocb_cmpl) | ||
523 | lpfc_sli_release_iocbq(phba, iocb); | ||
524 | else { | ||
525 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
526 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
527 | (iocb->iocb_cmpl) (phba, iocb, iocb); | ||
528 | } | ||
529 | } | ||
530 | |||
504 | lpfc_sli_abort_iocb_ring(phba, pring); | 531 | lpfc_sli_abort_iocb_ring(phba, pring); |
532 | spin_lock_irq(&phba->hbalock); | ||
505 | } | 533 | } |
534 | spin_unlock_irq(&phba->hbalock); | ||
506 | 535 | ||
507 | return 0; | 536 | return 0; |
508 | } | 537 | } |
@@ -641,6 +670,26 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) | |||
641 | } | 670 | } |
642 | } | 671 | } |
643 | 672 | ||
673 | static void | ||
674 | lpfc_offline_eratt(struct lpfc_hba *phba) | ||
675 | { | ||
676 | struct lpfc_sli *psli = &phba->sli; | ||
677 | |||
678 | spin_lock_irq(&phba->hbalock); | ||
679 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
680 | spin_unlock_irq(&phba->hbalock); | ||
681 | lpfc_offline_prep(phba); | ||
682 | |||
683 | lpfc_offline(phba); | ||
684 | lpfc_reset_barrier(phba); | ||
685 | lpfc_sli_brdreset(phba); | ||
686 | lpfc_hba_down_post(phba); | ||
687 | lpfc_sli_brdready(phba, HS_MBRDY); | ||
688 | lpfc_unblock_mgmt_io(phba); | ||
689 | phba->link_state = LPFC_HBA_ERROR; | ||
690 | return; | ||
691 | } | ||
692 | |||
644 | /************************************************************************/ | 693 | /************************************************************************/ |
645 | /* */ | 694 | /* */ |
646 | /* lpfc_handle_eratt */ | 695 | /* lpfc_handle_eratt */ |
@@ -681,14 +730,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
681 | vports = lpfc_create_vport_work_array(phba); | 730 | vports = lpfc_create_vport_work_array(phba); |
682 | if (vports != NULL) | 731 | if (vports != NULL) |
683 | for(i = 0; | 732 | for(i = 0; |
684 | i < LPFC_MAX_VPORTS && vports[i] != NULL; | 733 | i <= phba->max_vpi && vports[i] != NULL; |
685 | i++){ | 734 | i++){ |
686 | shost = lpfc_shost_from_vport(vports[i]); | 735 | shost = lpfc_shost_from_vport(vports[i]); |
687 | spin_lock_irq(shost->host_lock); | 736 | spin_lock_irq(shost->host_lock); |
688 | vports[i]->fc_flag |= FC_ESTABLISH_LINK; | 737 | vports[i]->fc_flag |= FC_ESTABLISH_LINK; |
689 | spin_unlock_irq(shost->host_lock); | 738 | spin_unlock_irq(shost->host_lock); |
690 | } | 739 | } |
691 | lpfc_destroy_vport_work_array(vports); | 740 | lpfc_destroy_vport_work_array(phba, vports); |
692 | spin_lock_irq(&phba->hbalock); | 741 | spin_lock_irq(&phba->hbalock); |
693 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 742 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
694 | spin_unlock_irq(&phba->hbalock); | 743 | spin_unlock_irq(&phba->hbalock); |
@@ -737,14 +786,9 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
737 | | PCI_VENDOR_ID_EMULEX); | 786 | | PCI_VENDOR_ID_EMULEX); |
738 | 787 | ||
739 | spin_lock_irq(&phba->hbalock); | 788 | spin_lock_irq(&phba->hbalock); |
740 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
741 | phba->over_temp_state = HBA_OVER_TEMP; | 789 | phba->over_temp_state = HBA_OVER_TEMP; |
742 | spin_unlock_irq(&phba->hbalock); | 790 | spin_unlock_irq(&phba->hbalock); |
743 | lpfc_offline_prep(phba); | 791 | lpfc_offline_eratt(phba); |
744 | lpfc_offline(phba); | ||
745 | lpfc_unblock_mgmt_io(phba); | ||
746 | phba->link_state = LPFC_HBA_ERROR; | ||
747 | lpfc_hba_down_post(phba); | ||
748 | 792 | ||
749 | } else { | 793 | } else { |
750 | /* The if clause above forces this code path when the status | 794 | /* The if clause above forces this code path when the status |
@@ -763,14 +807,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
763 | sizeof(event_data), (char *) &event_data, | 807 | sizeof(event_data), (char *) &event_data, |
764 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | 808 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); |
765 | 809 | ||
766 | spin_lock_irq(&phba->hbalock); | 810 | lpfc_offline_eratt(phba); |
767 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
768 | spin_unlock_irq(&phba->hbalock); | ||
769 | lpfc_offline_prep(phba); | ||
770 | lpfc_offline(phba); | ||
771 | lpfc_unblock_mgmt_io(phba); | ||
772 | phba->link_state = LPFC_HBA_ERROR; | ||
773 | lpfc_hba_down_post(phba); | ||
774 | } | 811 | } |
775 | } | 812 | } |
776 | 813 | ||
@@ -790,21 +827,25 @@ lpfc_handle_latt(struct lpfc_hba *phba) | |||
790 | LPFC_MBOXQ_t *pmb; | 827 | LPFC_MBOXQ_t *pmb; |
791 | volatile uint32_t control; | 828 | volatile uint32_t control; |
792 | struct lpfc_dmabuf *mp; | 829 | struct lpfc_dmabuf *mp; |
793 | int rc = -ENOMEM; | 830 | int rc = 0; |
794 | 831 | ||
795 | pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 832 | pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
796 | if (!pmb) | 833 | if (!pmb) { |
834 | rc = 1; | ||
797 | goto lpfc_handle_latt_err_exit; | 835 | goto lpfc_handle_latt_err_exit; |
836 | } | ||
798 | 837 | ||
799 | mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | 838 | mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); |
800 | if (!mp) | 839 | if (!mp) { |
840 | rc = 2; | ||
801 | goto lpfc_handle_latt_free_pmb; | 841 | goto lpfc_handle_latt_free_pmb; |
842 | } | ||
802 | 843 | ||
803 | mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); | 844 | mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); |
804 | if (!mp->virt) | 845 | if (!mp->virt) { |
846 | rc = 3; | ||
805 | goto lpfc_handle_latt_free_mp; | 847 | goto lpfc_handle_latt_free_mp; |
806 | 848 | } | |
807 | rc = -EIO; | ||
808 | 849 | ||
809 | /* Cleanup any outstanding ELS commands */ | 850 | /* Cleanup any outstanding ELS commands */ |
810 | lpfc_els_flush_all_cmd(phba); | 851 | lpfc_els_flush_all_cmd(phba); |
@@ -814,8 +855,10 @@ lpfc_handle_latt(struct lpfc_hba *phba) | |||
814 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; | 855 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; |
815 | pmb->vport = vport; | 856 | pmb->vport = vport; |
816 | rc = lpfc_sli_issue_mbox (phba, pmb, MBX_NOWAIT); | 857 | rc = lpfc_sli_issue_mbox (phba, pmb, MBX_NOWAIT); |
817 | if (rc == MBX_NOT_FINISHED) | 858 | if (rc == MBX_NOT_FINISHED) { |
859 | rc = 4; | ||
818 | goto lpfc_handle_latt_free_mbuf; | 860 | goto lpfc_handle_latt_free_mbuf; |
861 | } | ||
819 | 862 | ||
820 | /* Clear Link Attention in HA REG */ | 863 | /* Clear Link Attention in HA REG */ |
821 | spin_lock_irq(&phba->hbalock); | 864 | spin_lock_irq(&phba->hbalock); |
@@ -847,10 +890,8 @@ lpfc_handle_latt_err_exit: | |||
847 | lpfc_linkdown(phba); | 890 | lpfc_linkdown(phba); |
848 | phba->link_state = LPFC_HBA_ERROR; | 891 | phba->link_state = LPFC_HBA_ERROR; |
849 | 892 | ||
850 | /* The other case is an error from issue_mbox */ | 893 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
851 | if (rc == -ENOMEM) | 894 | "0300 LATT: Cannot issue READ_LA: Data:%d\n", rc); |
852 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, | ||
853 | "0300 READ_LA: no buffers\n"); | ||
854 | 895 | ||
855 | return; | 896 | return; |
856 | } | 897 | } |
@@ -1421,14 +1462,14 @@ lpfc_establish_link_tmo(unsigned long ptr) | |||
1421 | phba->pport->fc_flag, phba->pport->port_state); | 1462 | phba->pport->fc_flag, phba->pport->port_state); |
1422 | vports = lpfc_create_vport_work_array(phba); | 1463 | vports = lpfc_create_vport_work_array(phba); |
1423 | if (vports != NULL) | 1464 | if (vports != NULL) |
1424 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 1465 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
1425 | struct Scsi_Host *shost; | 1466 | struct Scsi_Host *shost; |
1426 | shost = lpfc_shost_from_vport(vports[i]); | 1467 | shost = lpfc_shost_from_vport(vports[i]); |
1427 | spin_lock_irqsave(shost->host_lock, iflag); | 1468 | spin_lock_irqsave(shost->host_lock, iflag); |
1428 | vports[i]->fc_flag &= ~FC_ESTABLISH_LINK; | 1469 | vports[i]->fc_flag &= ~FC_ESTABLISH_LINK; |
1429 | spin_unlock_irqrestore(shost->host_lock, iflag); | 1470 | spin_unlock_irqrestore(shost->host_lock, iflag); |
1430 | } | 1471 | } |
1431 | lpfc_destroy_vport_work_array(vports); | 1472 | lpfc_destroy_vport_work_array(phba, vports); |
1432 | } | 1473 | } |
1433 | 1474 | ||
1434 | void | 1475 | void |
@@ -1493,7 +1534,7 @@ lpfc_online(struct lpfc_hba *phba) | |||
1493 | 1534 | ||
1494 | vports = lpfc_create_vport_work_array(phba); | 1535 | vports = lpfc_create_vport_work_array(phba); |
1495 | if (vports != NULL) | 1536 | if (vports != NULL) |
1496 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 1537 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
1497 | struct Scsi_Host *shost; | 1538 | struct Scsi_Host *shost; |
1498 | shost = lpfc_shost_from_vport(vports[i]); | 1539 | shost = lpfc_shost_from_vport(vports[i]); |
1499 | spin_lock_irq(shost->host_lock); | 1540 | spin_lock_irq(shost->host_lock); |
@@ -1502,7 +1543,7 @@ lpfc_online(struct lpfc_hba *phba) | |||
1502 | vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 1543 | vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
1503 | spin_unlock_irq(shost->host_lock); | 1544 | spin_unlock_irq(shost->host_lock); |
1504 | } | 1545 | } |
1505 | lpfc_destroy_vport_work_array(vports); | 1546 | lpfc_destroy_vport_work_array(phba, vports); |
1506 | 1547 | ||
1507 | lpfc_unblock_mgmt_io(phba); | 1548 | lpfc_unblock_mgmt_io(phba); |
1508 | return 0; | 1549 | return 0; |
@@ -1536,7 +1577,7 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
1536 | /* Issue an unreg_login to all nodes on all vports */ | 1577 | /* Issue an unreg_login to all nodes on all vports */ |
1537 | vports = lpfc_create_vport_work_array(phba); | 1578 | vports = lpfc_create_vport_work_array(phba); |
1538 | if (vports != NULL) { | 1579 | if (vports != NULL) { |
1539 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 1580 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
1540 | struct Scsi_Host *shost; | 1581 | struct Scsi_Host *shost; |
1541 | 1582 | ||
1542 | if (vports[i]->load_flag & FC_UNLOADING) | 1583 | if (vports[i]->load_flag & FC_UNLOADING) |
@@ -1560,7 +1601,7 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
1560 | } | 1601 | } |
1561 | } | 1602 | } |
1562 | } | 1603 | } |
1563 | lpfc_destroy_vport_work_array(vports); | 1604 | lpfc_destroy_vport_work_array(phba, vports); |
1564 | 1605 | ||
1565 | lpfc_sli_flush_mbox_queue(phba); | 1606 | lpfc_sli_flush_mbox_queue(phba); |
1566 | } | 1607 | } |
@@ -1579,9 +1620,9 @@ lpfc_offline(struct lpfc_hba *phba) | |||
1579 | lpfc_stop_phba_timers(phba); | 1620 | lpfc_stop_phba_timers(phba); |
1580 | vports = lpfc_create_vport_work_array(phba); | 1621 | vports = lpfc_create_vport_work_array(phba); |
1581 | if (vports != NULL) | 1622 | if (vports != NULL) |
1582 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) | 1623 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) |
1583 | lpfc_stop_vport_timers(vports[i]); | 1624 | lpfc_stop_vport_timers(vports[i]); |
1584 | lpfc_destroy_vport_work_array(vports); | 1625 | lpfc_destroy_vport_work_array(phba, vports); |
1585 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | 1626 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, |
1586 | "0460 Bring Adapter offline\n"); | 1627 | "0460 Bring Adapter offline\n"); |
1587 | /* Bring down the SLI Layer and cleanup. The HBA is offline | 1628 | /* Bring down the SLI Layer and cleanup. The HBA is offline |
@@ -1592,14 +1633,14 @@ lpfc_offline(struct lpfc_hba *phba) | |||
1592 | spin_unlock_irq(&phba->hbalock); | 1633 | spin_unlock_irq(&phba->hbalock); |
1593 | vports = lpfc_create_vport_work_array(phba); | 1634 | vports = lpfc_create_vport_work_array(phba); |
1594 | if (vports != NULL) | 1635 | if (vports != NULL) |
1595 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 1636 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
1596 | shost = lpfc_shost_from_vport(vports[i]); | 1637 | shost = lpfc_shost_from_vport(vports[i]); |
1597 | spin_lock_irq(shost->host_lock); | 1638 | spin_lock_irq(shost->host_lock); |
1598 | vports[i]->work_port_events = 0; | 1639 | vports[i]->work_port_events = 0; |
1599 | vports[i]->fc_flag |= FC_OFFLINE_MODE; | 1640 | vports[i]->fc_flag |= FC_OFFLINE_MODE; |
1600 | spin_unlock_irq(shost->host_lock); | 1641 | spin_unlock_irq(shost->host_lock); |
1601 | } | 1642 | } |
1602 | lpfc_destroy_vport_work_array(vports); | 1643 | lpfc_destroy_vport_work_array(phba, vports); |
1603 | } | 1644 | } |
1604 | 1645 | ||
1605 | /****************************************************************************** | 1646 | /****************************************************************************** |
@@ -2149,6 +2190,8 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
2149 | kfree(vport->vname); | 2190 | kfree(vport->vname); |
2150 | lpfc_free_sysfs_attr(vport); | 2191 | lpfc_free_sysfs_attr(vport); |
2151 | 2192 | ||
2193 | kthread_stop(phba->worker_thread); | ||
2194 | |||
2152 | fc_remove_host(shost); | 2195 | fc_remove_host(shost); |
2153 | scsi_remove_host(shost); | 2196 | scsi_remove_host(shost); |
2154 | lpfc_cleanup(vport); | 2197 | lpfc_cleanup(vport); |
@@ -2168,8 +2211,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
2168 | 2211 | ||
2169 | lpfc_debugfs_terminate(vport); | 2212 | lpfc_debugfs_terminate(vport); |
2170 | 2213 | ||
2171 | kthread_stop(phba->worker_thread); | ||
2172 | |||
2173 | /* Release the irq reservation */ | 2214 | /* Release the irq reservation */ |
2174 | free_irq(phba->pcidev->irq, phba); | 2215 | free_irq(phba->pcidev->irq, phba); |
2175 | if (phba->using_msi) | 2216 | if (phba->using_msi) |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 6b64e573ad4e..dfc63f6ccd7b 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -896,7 +896,7 @@ lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) | |||
896 | case MBX_DOWN_LOAD: /* 0x1C */ | 896 | case MBX_DOWN_LOAD: /* 0x1C */ |
897 | case MBX_DEL_LD_ENTRY: /* 0x1D */ | 897 | case MBX_DEL_LD_ENTRY: /* 0x1D */ |
898 | case MBX_LOAD_AREA: /* 0x81 */ | 898 | case MBX_LOAD_AREA: /* 0x81 */ |
899 | case MBX_FLASH_WR_ULA: /* 0x98 */ | 899 | case MBX_WRITE_WWN: /* 0x98 */ |
900 | case MBX_LOAD_EXP_ROM: /* 0x9C */ | 900 | case MBX_LOAD_EXP_ROM: /* 0x9C */ |
901 | return LPFC_MBOX_TMO_FLASH_CMD; | 901 | return LPFC_MBOX_TMO_FLASH_CMD; |
902 | } | 902 | } |
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 43c3b8a0d76a..6dc5ab8d6716 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
@@ -98,6 +98,7 @@ lpfc_mem_alloc(struct lpfc_hba * phba) | |||
98 | 98 | ||
99 | fail_free_hbq_pool: | 99 | fail_free_hbq_pool: |
100 | lpfc_sli_hbqbuf_free_all(phba); | 100 | lpfc_sli_hbqbuf_free_all(phba); |
101 | pci_pool_destroy(phba->lpfc_hbq_pool); | ||
101 | fail_free_nlp_mem_pool: | 102 | fail_free_nlp_mem_pool: |
102 | mempool_destroy(phba->nlp_mem_pool); | 103 | mempool_destroy(phba->nlp_mem_pool); |
103 | phba->nlp_mem_pool = NULL; | 104 | phba->nlp_mem_pool = NULL; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index c987c4fcdadc..648795806a83 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -130,7 +130,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) | |||
130 | 130 | ||
131 | vports = lpfc_create_vport_work_array(phba); | 131 | vports = lpfc_create_vport_work_array(phba); |
132 | if (vports != NULL) | 132 | if (vports != NULL) |
133 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 133 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
134 | shost = lpfc_shost_from_vport(vports[i]); | 134 | shost = lpfc_shost_from_vport(vports[i]); |
135 | shost_for_each_device(sdev, shost) { | 135 | shost_for_each_device(sdev, shost) { |
136 | new_queue_depth = | 136 | new_queue_depth = |
@@ -151,7 +151,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) | |||
151 | new_queue_depth); | 151 | new_queue_depth); |
152 | } | 152 | } |
153 | } | 153 | } |
154 | lpfc_destroy_vport_work_array(vports); | 154 | lpfc_destroy_vport_work_array(phba, vports); |
155 | atomic_set(&phba->num_rsrc_err, 0); | 155 | atomic_set(&phba->num_rsrc_err, 0); |
156 | atomic_set(&phba->num_cmd_success, 0); | 156 | atomic_set(&phba->num_cmd_success, 0); |
157 | } | 157 | } |
@@ -166,7 +166,7 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) | |||
166 | 166 | ||
167 | vports = lpfc_create_vport_work_array(phba); | 167 | vports = lpfc_create_vport_work_array(phba); |
168 | if (vports != NULL) | 168 | if (vports != NULL) |
169 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 169 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
170 | shost = lpfc_shost_from_vport(vports[i]); | 170 | shost = lpfc_shost_from_vport(vports[i]); |
171 | shost_for_each_device(sdev, shost) { | 171 | shost_for_each_device(sdev, shost) { |
172 | if (sdev->ordered_tags) | 172 | if (sdev->ordered_tags) |
@@ -179,7 +179,7 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) | |||
179 | sdev->queue_depth+1); | 179 | sdev->queue_depth+1); |
180 | } | 180 | } |
181 | } | 181 | } |
182 | lpfc_destroy_vport_work_array(vports); | 182 | lpfc_destroy_vport_work_array(phba, vports); |
183 | atomic_set(&phba->num_rsrc_err, 0); | 183 | atomic_set(&phba->num_rsrc_err, 0); |
184 | atomic_set(&phba->num_cmd_success, 0); | 184 | atomic_set(&phba->num_cmd_success, 0); |
185 | } | 185 | } |
@@ -380,7 +380,7 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
380 | (num_bde * sizeof (struct ulp_bde64)); | 380 | (num_bde * sizeof (struct ulp_bde64)); |
381 | iocb_cmd->ulpBdeCount = 1; | 381 | iocb_cmd->ulpBdeCount = 1; |
382 | iocb_cmd->ulpLe = 1; | 382 | iocb_cmd->ulpLe = 1; |
383 | fcp_cmnd->fcpDl = be32_to_cpu(scsi_bufflen(scsi_cmnd)); | 383 | fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); |
384 | return 0; | 384 | return 0; |
385 | } | 385 | } |
386 | 386 | ||
@@ -763,6 +763,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
763 | piocbq->iocb.ulpContext = pnode->nlp_rpi; | 763 | piocbq->iocb.ulpContext = pnode->nlp_rpi; |
764 | if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE) | 764 | if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE) |
765 | piocbq->iocb.ulpFCP2Rcvy = 1; | 765 | piocbq->iocb.ulpFCP2Rcvy = 1; |
766 | else | ||
767 | piocbq->iocb.ulpFCP2Rcvy = 0; | ||
766 | 768 | ||
767 | piocbq->iocb.ulpClass = (pnode->nlp_fcp_info & 0x0f); | 769 | piocbq->iocb.ulpClass = (pnode->nlp_fcp_info & 0x0f); |
768 | piocbq->context1 = lpfc_cmd; | 770 | piocbq->context1 = lpfc_cmd; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 46d529d6ac6b..5a2cb484e137 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -716,7 +716,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
716 | case MBX_DEL_LD_ENTRY: | 716 | case MBX_DEL_LD_ENTRY: |
717 | case MBX_RUN_PROGRAM: | 717 | case MBX_RUN_PROGRAM: |
718 | case MBX_SET_MASK: | 718 | case MBX_SET_MASK: |
719 | case MBX_SET_SLIM: | 719 | case MBX_SET_VARIABLE: |
720 | case MBX_UNREG_D_ID: | 720 | case MBX_UNREG_D_ID: |
721 | case MBX_KILL_BOARD: | 721 | case MBX_KILL_BOARD: |
722 | case MBX_CONFIG_FARP: | 722 | case MBX_CONFIG_FARP: |
@@ -728,7 +728,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
728 | case MBX_READ_RPI64: | 728 | case MBX_READ_RPI64: |
729 | case MBX_REG_LOGIN64: | 729 | case MBX_REG_LOGIN64: |
730 | case MBX_READ_LA64: | 730 | case MBX_READ_LA64: |
731 | case MBX_FLASH_WR_ULA: | 731 | case MBX_WRITE_WWN: |
732 | case MBX_SET_DEBUG: | 732 | case MBX_SET_DEBUG: |
733 | case MBX_LOAD_EXP_ROM: | 733 | case MBX_LOAD_EXP_ROM: |
734 | case MBX_ASYNCEVT_ENABLE: | 734 | case MBX_ASYNCEVT_ENABLE: |
@@ -2182,7 +2182,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2182 | <status> */ | 2182 | <status> */ |
2183 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2183 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2184 | "0436 Adapter failed to init, " | 2184 | "0436 Adapter failed to init, " |
2185 | "timeout, status reg x%x\n", status); | 2185 | "timeout, status reg x%x, " |
2186 | "FW Data: A8 x%x AC x%x\n", status, | ||
2187 | readl(phba->MBslimaddr + 0xa8), | ||
2188 | readl(phba->MBslimaddr + 0xac)); | ||
2186 | phba->link_state = LPFC_HBA_ERROR; | 2189 | phba->link_state = LPFC_HBA_ERROR; |
2187 | return -ETIMEDOUT; | 2190 | return -ETIMEDOUT; |
2188 | } | 2191 | } |
@@ -2194,7 +2197,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2194 | <status> */ | 2197 | <status> */ |
2195 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2198 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2196 | "0437 Adapter failed to init, " | 2199 | "0437 Adapter failed to init, " |
2197 | "chipset, status reg x%x\n", status); | 2200 | "chipset, status reg x%x, " |
2201 | "FW Data: A8 x%x AC x%x\n", status, | ||
2202 | readl(phba->MBslimaddr + 0xa8), | ||
2203 | readl(phba->MBslimaddr + 0xac)); | ||
2198 | phba->link_state = LPFC_HBA_ERROR; | 2204 | phba->link_state = LPFC_HBA_ERROR; |
2199 | return -EIO; | 2205 | return -EIO; |
2200 | } | 2206 | } |
@@ -2222,7 +2228,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2222 | /* Adapter failed to init, chipset, status reg <status> */ | 2228 | /* Adapter failed to init, chipset, status reg <status> */ |
2223 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2229 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2224 | "0438 Adapter failed to init, chipset, " | 2230 | "0438 Adapter failed to init, chipset, " |
2225 | "status reg x%x\n", status); | 2231 | "status reg x%x, " |
2232 | "FW Data: A8 x%x AC x%x\n", status, | ||
2233 | readl(phba->MBslimaddr + 0xa8), | ||
2234 | readl(phba->MBslimaddr + 0xac)); | ||
2226 | phba->link_state = LPFC_HBA_ERROR; | 2235 | phba->link_state = LPFC_HBA_ERROR; |
2227 | return -EIO; | 2236 | return -EIO; |
2228 | } | 2237 | } |
@@ -2581,6 +2590,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2581 | uint32_t status, evtctr; | 2590 | uint32_t status, evtctr; |
2582 | uint32_t ha_copy; | 2591 | uint32_t ha_copy; |
2583 | int i; | 2592 | int i; |
2593 | unsigned long timeout; | ||
2584 | unsigned long drvr_flag = 0; | 2594 | unsigned long drvr_flag = 0; |
2585 | volatile uint32_t word0, ldata; | 2595 | volatile uint32_t word0, ldata; |
2586 | void __iomem *to_slim; | 2596 | void __iomem *to_slim; |
@@ -2756,18 +2766,24 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2756 | } | 2766 | } |
2757 | 2767 | ||
2758 | wmb(); | 2768 | wmb(); |
2759 | /* interrupt board to doit right away */ | ||
2760 | writel(CA_MBATT, phba->CAregaddr); | ||
2761 | readl(phba->CAregaddr); /* flush */ | ||
2762 | 2769 | ||
2763 | switch (flag) { | 2770 | switch (flag) { |
2764 | case MBX_NOWAIT: | 2771 | case MBX_NOWAIT: |
2765 | /* Don't wait for it to finish, just return */ | 2772 | /* Set up reference to mailbox command */ |
2766 | psli->mbox_active = pmbox; | 2773 | psli->mbox_active = pmbox; |
2774 | /* Interrupt board to do it */ | ||
2775 | writel(CA_MBATT, phba->CAregaddr); | ||
2776 | readl(phba->CAregaddr); /* flush */ | ||
2777 | /* Don't wait for it to finish, just return */ | ||
2767 | break; | 2778 | break; |
2768 | 2779 | ||
2769 | case MBX_POLL: | 2780 | case MBX_POLL: |
2781 | /* Set up null reference to mailbox command */ | ||
2770 | psli->mbox_active = NULL; | 2782 | psli->mbox_active = NULL; |
2783 | /* Interrupt board to do it */ | ||
2784 | writel(CA_MBATT, phba->CAregaddr); | ||
2785 | readl(phba->CAregaddr); /* flush */ | ||
2786 | |||
2771 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { | 2787 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { |
2772 | /* First read mbox status word */ | 2788 | /* First read mbox status word */ |
2773 | word0 = *((volatile uint32_t *)&phba->slim2p->mbx); | 2789 | word0 = *((volatile uint32_t *)&phba->slim2p->mbx); |
@@ -2779,15 +2795,15 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2779 | 2795 | ||
2780 | /* Read the HBA Host Attention Register */ | 2796 | /* Read the HBA Host Attention Register */ |
2781 | ha_copy = readl(phba->HAregaddr); | 2797 | ha_copy = readl(phba->HAregaddr); |
2782 | 2798 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, | |
2783 | i = lpfc_mbox_tmo_val(phba, mb->mbxCommand); | 2799 | mb->mbxCommand) * |
2784 | i *= 1000; /* Convert to ms */ | 2800 | 1000) + jiffies; |
2785 | 2801 | i = 0; | |
2786 | /* Wait for command to complete */ | 2802 | /* Wait for command to complete */ |
2787 | while (((word0 & OWN_CHIP) == OWN_CHIP) || | 2803 | while (((word0 & OWN_CHIP) == OWN_CHIP) || |
2788 | (!(ha_copy & HA_MBATT) && | 2804 | (!(ha_copy & HA_MBATT) && |
2789 | (phba->link_state > LPFC_WARM_START))) { | 2805 | (phba->link_state > LPFC_WARM_START))) { |
2790 | if (i-- <= 0) { | 2806 | if (time_after(jiffies, timeout)) { |
2791 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2807 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2792 | spin_unlock_irqrestore(&phba->hbalock, | 2808 | spin_unlock_irqrestore(&phba->hbalock, |
2793 | drvr_flag); | 2809 | drvr_flag); |
@@ -2800,12 +2816,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2800 | && (evtctr != psli->slistat.mbox_event)) | 2816 | && (evtctr != psli->slistat.mbox_event)) |
2801 | break; | 2817 | break; |
2802 | 2818 | ||
2803 | spin_unlock_irqrestore(&phba->hbalock, | 2819 | if (i++ > 10) { |
2804 | drvr_flag); | 2820 | spin_unlock_irqrestore(&phba->hbalock, |
2805 | 2821 | drvr_flag); | |
2806 | msleep(1); | 2822 | msleep(1); |
2807 | 2823 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | |
2808 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | 2824 | } |
2809 | 2825 | ||
2810 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { | 2826 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { |
2811 | /* First copy command data */ | 2827 | /* First copy command data */ |
@@ -3065,7 +3081,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba, | |||
3065 | if (evt_code == ASYNC_TEMP_WARN) { | 3081 | if (evt_code == ASYNC_TEMP_WARN) { |
3066 | temp_event_data.event_code = LPFC_THRESHOLD_TEMP; | 3082 | temp_event_data.event_code = LPFC_THRESHOLD_TEMP; |
3067 | lpfc_printf_log(phba, | 3083 | lpfc_printf_log(phba, |
3068 | KERN_WARNING, | 3084 | KERN_ERR, |
3069 | LOG_TEMP, | 3085 | LOG_TEMP, |
3070 | "0347 Adapter is very hot, please take " | 3086 | "0347 Adapter is very hot, please take " |
3071 | "corrective action. temperature : %d Celsius\n", | 3087 | "corrective action. temperature : %d Celsius\n", |
@@ -3074,7 +3090,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba, | |||
3074 | if (evt_code == ASYNC_TEMP_SAFE) { | 3090 | if (evt_code == ASYNC_TEMP_SAFE) { |
3075 | temp_event_data.event_code = LPFC_NORMAL_TEMP; | 3091 | temp_event_data.event_code = LPFC_NORMAL_TEMP; |
3076 | lpfc_printf_log(phba, | 3092 | lpfc_printf_log(phba, |
3077 | KERN_INFO, | 3093 | KERN_ERR, |
3078 | LOG_TEMP, | 3094 | LOG_TEMP, |
3079 | "0340 Adapter temperature is OK now. " | 3095 | "0340 Adapter temperature is OK now. " |
3080 | "temperature : %d Celsius\n", | 3096 | "temperature : %d Celsius\n", |
@@ -4047,7 +4063,6 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4047 | } | 4063 | } |
4048 | 4064 | ||
4049 | if (work_ha_copy & HA_ERATT) { | 4065 | if (work_ha_copy & HA_ERATT) { |
4050 | phba->link_state = LPFC_HBA_ERROR; | ||
4051 | /* | 4066 | /* |
4052 | * There was a link/board error. Read the | 4067 | * There was a link/board error. Read the |
4053 | * status register to retrieve the error event | 4068 | * status register to retrieve the error event |
@@ -4079,7 +4094,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4079 | * Stray Mailbox Interrupt, mbxCommand <cmd> | 4094 | * Stray Mailbox Interrupt, mbxCommand <cmd> |
4080 | * mbxStatus <status> | 4095 | * mbxStatus <status> |
4081 | */ | 4096 | */ |
4082 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | | 4097 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | |
4083 | LOG_SLI, | 4098 | LOG_SLI, |
4084 | "(%d):0304 Stray Mailbox " | 4099 | "(%d):0304 Stray Mailbox " |
4085 | "Interrupt mbxCommand x%x " | 4100 | "Interrupt mbxCommand x%x " |
@@ -4087,51 +4102,60 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4087 | (vport ? vport->vpi : 0), | 4102 | (vport ? vport->vpi : 0), |
4088 | pmbox->mbxCommand, | 4103 | pmbox->mbxCommand, |
4089 | pmbox->mbxStatus); | 4104 | pmbox->mbxStatus); |
4090 | } | 4105 | /* clear mailbox attention bit */ |
4091 | phba->last_completion_time = jiffies; | 4106 | work_ha_copy &= ~HA_MBATT; |
4092 | del_timer_sync(&phba->sli.mbox_tmo); | 4107 | } else { |
4093 | 4108 | phba->last_completion_time = jiffies; | |
4094 | phba->sli.mbox_active = NULL; | 4109 | del_timer(&phba->sli.mbox_tmo); |
4095 | if (pmb->mbox_cmpl) { | ||
4096 | lpfc_sli_pcimem_bcopy(mbox, pmbox, | ||
4097 | MAILBOX_CMD_SIZE); | ||
4098 | } | ||
4099 | if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) { | ||
4100 | pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG; | ||
4101 | 4110 | ||
4102 | lpfc_debugfs_disc_trc(vport, | 4111 | phba->sli.mbox_active = NULL; |
4103 | LPFC_DISC_TRC_MBOX_VPORT, | 4112 | if (pmb->mbox_cmpl) { |
4104 | "MBOX dflt rpi: : status:x%x rpi:x%x", | 4113 | lpfc_sli_pcimem_bcopy(mbox, pmbox, |
4105 | (uint32_t)pmbox->mbxStatus, | 4114 | MAILBOX_CMD_SIZE); |
4106 | pmbox->un.varWords[0], 0); | 4115 | } |
4107 | 4116 | if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) { | |
4108 | if ( !pmbox->mbxStatus) { | 4117 | pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG; |
4109 | mp = (struct lpfc_dmabuf *) | 4118 | |
4110 | (pmb->context1); | 4119 | lpfc_debugfs_disc_trc(vport, |
4111 | ndlp = (struct lpfc_nodelist *) | 4120 | LPFC_DISC_TRC_MBOX_VPORT, |
4112 | pmb->context2; | 4121 | "MBOX dflt rpi: : " |
4113 | 4122 | "status:x%x rpi:x%x", | |
4114 | /* Reg_LOGIN of dflt RPI was successful. | 4123 | (uint32_t)pmbox->mbxStatus, |
4115 | * new lets get rid of the RPI using the | 4124 | pmbox->un.varWords[0], 0); |
4116 | * same mbox buffer. | 4125 | |
4117 | */ | 4126 | if (!pmbox->mbxStatus) { |
4118 | lpfc_unreg_login(phba, vport->vpi, | 4127 | mp = (struct lpfc_dmabuf *) |
4119 | pmbox->un.varWords[0], pmb); | 4128 | (pmb->context1); |
4120 | pmb->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | 4129 | ndlp = (struct lpfc_nodelist *) |
4121 | pmb->context1 = mp; | 4130 | pmb->context2; |
4122 | pmb->context2 = ndlp; | 4131 | |
4123 | pmb->vport = vport; | 4132 | /* Reg_LOGIN of dflt RPI was |
4124 | spin_lock(&phba->hbalock); | 4133 | * successful. new lets get |
4125 | phba->sli.sli_flag &= | 4134 | * rid of the RPI using the |
4126 | ~LPFC_SLI_MBOX_ACTIVE; | 4135 | * same mbox buffer. |
4127 | spin_unlock(&phba->hbalock); | 4136 | */ |
4128 | goto send_current_mbox; | 4137 | lpfc_unreg_login(phba, |
4138 | vport->vpi, | ||
4139 | pmbox->un.varWords[0], | ||
4140 | pmb); | ||
4141 | pmb->mbox_cmpl = | ||
4142 | lpfc_mbx_cmpl_dflt_rpi; | ||
4143 | pmb->context1 = mp; | ||
4144 | pmb->context2 = ndlp; | ||
4145 | pmb->vport = vport; | ||
4146 | spin_lock(&phba->hbalock); | ||
4147 | phba->sli.sli_flag &= | ||
4148 | ~LPFC_SLI_MBOX_ACTIVE; | ||
4149 | spin_unlock(&phba->hbalock); | ||
4150 | goto send_current_mbox; | ||
4151 | } | ||
4129 | } | 4152 | } |
4153 | spin_lock(&phba->pport->work_port_lock); | ||
4154 | phba->pport->work_port_events &= | ||
4155 | ~WORKER_MBOX_TMO; | ||
4156 | spin_unlock(&phba->pport->work_port_lock); | ||
4157 | lpfc_mbox_cmpl_put(phba, pmb); | ||
4130 | } | 4158 | } |
4131 | spin_lock(&phba->pport->work_port_lock); | ||
4132 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; | ||
4133 | spin_unlock(&phba->pport->work_port_lock); | ||
4134 | lpfc_mbox_cmpl_put(phba, pmb); | ||
4135 | } | 4159 | } |
4136 | if ((work_ha_copy & HA_MBATT) && | 4160 | if ((work_ha_copy & HA_MBATT) && |
4137 | (phba->sli.mbox_active == NULL)) { | 4161 | (phba->sli.mbox_active == NULL)) { |
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 07a28700cbe7..9fad7663c117 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -562,7 +562,7 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba) | |||
562 | struct lpfc_vport *port_iterator; | 562 | struct lpfc_vport *port_iterator; |
563 | struct lpfc_vport **vports; | 563 | struct lpfc_vport **vports; |
564 | int index = 0; | 564 | int index = 0; |
565 | vports = kzalloc(LPFC_MAX_VPORTS * sizeof(struct lpfc_vport *), | 565 | vports = kzalloc((phba->max_vpi + 1) * sizeof(struct lpfc_vport *), |
566 | GFP_KERNEL); | 566 | GFP_KERNEL); |
567 | if (vports == NULL) | 567 | if (vports == NULL) |
568 | return NULL; | 568 | return NULL; |
@@ -581,12 +581,12 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba) | |||
581 | } | 581 | } |
582 | 582 | ||
583 | void | 583 | void |
584 | lpfc_destroy_vport_work_array(struct lpfc_vport **vports) | 584 | lpfc_destroy_vport_work_array(struct lpfc_hba *phba, struct lpfc_vport **vports) |
585 | { | 585 | { |
586 | int i; | 586 | int i; |
587 | if (vports == NULL) | 587 | if (vports == NULL) |
588 | return; | 588 | return; |
589 | for (i=0; vports[i] != NULL && i < LPFC_MAX_VPORTS; i++) | 589 | for (i=0; vports[i] != NULL && i <= phba->max_vpi; i++) |
590 | scsi_host_put(lpfc_shost_from_vport(vports[i])); | 590 | scsi_host_put(lpfc_shost_from_vport(vports[i])); |
591 | kfree(vports); | 591 | kfree(vports); |
592 | } | 592 | } |
diff --git a/drivers/scsi/lpfc/lpfc_vport.h b/drivers/scsi/lpfc/lpfc_vport.h index 91da17751a37..96c445333b69 100644 --- a/drivers/scsi/lpfc/lpfc_vport.h +++ b/drivers/scsi/lpfc/lpfc_vport.h | |||
@@ -89,7 +89,7 @@ int lpfc_vport_delete(struct fc_vport *); | |||
89 | int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *); | 89 | int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *); |
90 | int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint); | 90 | int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint); |
91 | struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *); | 91 | struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *); |
92 | void lpfc_destroy_vport_work_array(struct lpfc_vport **); | 92 | void lpfc_destroy_vport_work_array(struct lpfc_hba *, struct lpfc_vport **); |
93 | 93 | ||
94 | /* | 94 | /* |
95 | * queuecommand VPORT-specific return codes. Specified in the host byte code. | 95 | * queuecommand VPORT-specific return codes. Specified in the host byte code. |