aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-04-25 09:52:34 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-06 10:33:14 -0400
commit7054a606e6724674a5acd103ed74eacb02c73393 (patch)
tree271327c20a1e4bff9475ef7a9d98afd4644d6570
parentde0c5b32b50ef2673f4cd434b9c2732237d715dd (diff)
[SCSI] lpfc 8.1.12 : Round 2 of Miscellaneous fixes
Round 2 of Miscellaneous fixes: - Ensure we don't prematurely re-enable IRQs in lpfc_sli_abort_fcp_cmpl(). - Prevent freeing of iocb after IOCB_TIMEDOUT error. - Added code to cleanup REG_LOGIN mailbox command when a LOGO is received. - Fix offline window where more work can sneak in after clearing work_ha - Use target reset instead of LU reset in bus_device_reset_handler - Fixed system hangs due to leaked host_lock. - Fixed NULL pointer dereference during I/O with LIP. - Fixed false iocb timeout. - Fixed name server query response handling. - Change rport dev_loss_tmo value when user change lpfc HBA's dev_loss_tmo. - Fixed a memory leak in lpfc_sli_wake_mbox_wait. - Fixed check for dropped frames. - Removed hba queue depth calculation based on device PCI IDs - Change min cr_count value specified in comment to agree with setting Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/lpfc/lpfc.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c35
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c6
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c12
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c27
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c90
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c66
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h3
9 files changed, 168 insertions, 79 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 6aa91530fcde..b7193d1a90f6 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -27,10 +27,6 @@ struct lpfc_sli2_slim;
27 requests */ 27 requests */
28#define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact 28#define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact
29 the NameServer before giving up. */ 29 the NameServer before giving up. */
30#define LPFC_DFT_HBA_Q_DEPTH 2048 /* max cmds per hba */
31#define LPFC_LC_HBA_Q_DEPTH 1024 /* max cmds per low cost hba */
32#define LPFC_LP101_HBA_Q_DEPTH 128 /* max cmds per low cost hba */
33
34#define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ 30#define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */
35#define LPFC_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ 31#define LPFC_SG_SEG_CNT 64 /* sg element count per scsi cmnd */
36#define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ 32#define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index c0b02b11d88f..7811aaf114d5 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -828,6 +828,18 @@ lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val)
828 return -EINVAL; 828 return -EINVAL;
829} 829}
830 830
831static void
832lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba)
833{
834 struct lpfc_nodelist *ndlp;
835
836 spin_lock_irq(phba->host->host_lock);
837 list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp)
838 if (ndlp->rport)
839 ndlp->rport->dev_loss_tmo = phba->cfg_devloss_tmo;
840 spin_unlock_irq(phba->host->host_lock);
841}
842
831static int 843static int
832lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) 844lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val)
833{ 845{
@@ -843,6 +855,7 @@ lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val)
843 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { 855 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
844 phba->cfg_nodev_tmo = val; 856 phba->cfg_nodev_tmo = val;
845 phba->cfg_devloss_tmo = val; 857 phba->cfg_devloss_tmo = val;
858 lpfc_update_rport_devloss_tmo(phba);
846 return 0; 859 return 0;
847 } 860 }
848 861
@@ -878,6 +891,7 @@ lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val)
878 phba->cfg_nodev_tmo = val; 891 phba->cfg_nodev_tmo = val;
879 phba->cfg_devloss_tmo = val; 892 phba->cfg_devloss_tmo = val;
880 phba->dev_loss_tmo_changed = 1; 893 phba->dev_loss_tmo_changed = 1;
894 lpfc_update_rport_devloss_tmo(phba);
881 return 0; 895 return 0;
882 } 896 }
883 897
@@ -997,7 +1011,7 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
997/* 1011/*
998# lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing 1012# lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
999# cr_delay (msec) or cr_count outstanding commands. cr_delay can take 1013# cr_delay (msec) or cr_count outstanding commands. cr_delay can take
1000# value [0,63]. cr_count can take value [0,255]. Default value of cr_delay 1014# value [0,63]. cr_count can take value [1,255]. Default value of cr_delay
1001# is 0. Default value of cr_count is 1. The cr_count feature is disabled if 1015# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
1002# cr_delay is set to 0. 1016# cr_delay is set to 0.
1003*/ 1017*/
@@ -1955,25 +1969,8 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
1955 sizeof(struct fcp_rsp) + 1969 sizeof(struct fcp_rsp) +
1956 (phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64)); 1970 (phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64));
1957 1971
1958 switch (phba->pcidev->device) {
1959 case PCI_DEVICE_ID_LP101:
1960 case PCI_DEVICE_ID_BSMB:
1961 case PCI_DEVICE_ID_ZSMB:
1962 phba->cfg_hba_queue_depth = LPFC_LP101_HBA_Q_DEPTH;
1963 break;
1964 case PCI_DEVICE_ID_RFLY:
1965 case PCI_DEVICE_ID_PFLY:
1966 case PCI_DEVICE_ID_BMID:
1967 case PCI_DEVICE_ID_ZMID:
1968 case PCI_DEVICE_ID_TFLY:
1969 phba->cfg_hba_queue_depth = LPFC_LC_HBA_Q_DEPTH;
1970 break;
1971 default:
1972 phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH;
1973 }
1974 1972
1975 if (phba->cfg_hba_queue_depth > lpfc_hba_queue_depth) 1973 lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
1976 lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
1977 1974
1978 return; 1975 return;
1979} 1976}
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 50f45339e0c0..48ae2355de69 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -334,22 +334,22 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)
334 334
335 lpfc_set_disctmo(phba); 335 lpfc_set_disctmo(phba);
336 336
337 Cnt = Size > FCELSSIZE ? FCELSSIZE : Size;
338 337
339 list_add_tail(&head, &mp->list); 338 list_add_tail(&head, &mp->list);
340 list_for_each_entry_safe(mp, next_mp, &head, list) { 339 list_for_each_entry_safe(mp, next_mp, &head, list) {
341 mlast = mp; 340 mlast = mp;
342 341
342 Cnt = Size > FCELSSIZE ? FCELSSIZE : Size;
343
343 Size -= Cnt; 344 Size -= Cnt;
344 345
345 if (!ctptr) { 346 if (!ctptr) {
346 Cnt = FCELSSIZE;
347 ctptr = (uint32_t *) mlast->virt; 347 ctptr = (uint32_t *) mlast->virt;
348 } else 348 } else
349 Cnt -= 16; /* subtract length of CT header */ 349 Cnt -= 16; /* subtract length of CT header */
350 350
351 /* Loop through entire NameServer list of DIDs */ 351 /* Loop through entire NameServer list of DIDs */
352 while (Cnt) { 352 while (Cnt >= sizeof (uint32_t)) {
353 353
354 /* Get next DID from NameServer List */ 354 /* Get next DID from NameServer List */
355 CTentry = *ctptr++; 355 CTentry = *ctptr++;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 14266dfb35db..4d9e7f50c189 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -3214,7 +3214,7 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
3214 IOCB_t *cmd = NULL; 3214 IOCB_t *cmd = NULL;
3215 struct lpfc_dmabuf *pcmd; 3215 struct lpfc_dmabuf *pcmd;
3216 uint32_t *elscmd; 3216 uint32_t *elscmd;
3217 uint32_t els_command; 3217 uint32_t els_command=0;
3218 uint32_t timeout; 3218 uint32_t timeout;
3219 uint32_t remote_ID; 3219 uint32_t remote_ID;
3220 3220
@@ -3233,12 +3233,16 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
3233 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { 3233 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
3234 cmd = &piocb->iocb; 3234 cmd = &piocb->iocb;
3235 3235
3236 if (piocb->iocb_flag & LPFC_IO_LIBDFC) { 3236 if ((piocb->iocb_flag & LPFC_IO_LIBDFC) ||
3237 (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN) ||
3238 (piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)) {
3237 continue; 3239 continue;
3238 } 3240 }
3239 pcmd = (struct lpfc_dmabuf *) piocb->context2; 3241 pcmd = (struct lpfc_dmabuf *) piocb->context2;
3240 elscmd = (uint32_t *) (pcmd->virt); 3242 if (pcmd) {
3241 els_command = *elscmd; 3243 elscmd = (uint32_t *) (pcmd->virt);
3244 els_command = *elscmd;
3245 }
3242 3246
3243 if ((els_command == ELS_CMD_FARP) 3247 if ((els_command == ELS_CMD_FARP)
3244 || (els_command == ELS_CMD_FARPR)) { 3248 || (els_command == ELS_CMD_FARPR)) {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 5f013f1cdead..6449ac8fca24 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1375,8 +1375,6 @@ lpfc_offline(struct lpfc_hba * phba)
1375 1375
1376 /* stop all timers associated with this hba */ 1376 /* stop all timers associated with this hba */
1377 lpfc_stop_timer(phba); 1377 lpfc_stop_timer(phba);
1378 phba->work_hba_events = 0;
1379 phba->work_ha = 0;
1380 1378
1381 lpfc_printf_log(phba, 1379 lpfc_printf_log(phba,
1382 KERN_WARNING, 1380 KERN_WARNING,
@@ -1389,6 +1387,8 @@ lpfc_offline(struct lpfc_hba * phba)
1389 lpfc_sli_hba_down(phba); 1387 lpfc_sli_hba_down(phba);
1390 lpfc_cleanup(phba); 1388 lpfc_cleanup(phba);
1391 spin_lock_irqsave(phba->host->host_lock, iflag); 1389 spin_lock_irqsave(phba->host->host_lock, iflag);
1390 phba->work_hba_events = 0;
1391 phba->work_ha = 0;
1392 phba->fc_flag |= FC_OFFLINE_MODE; 1392 phba->fc_flag |= FC_OFFLINE_MODE;
1393 spin_unlock_irqrestore(phba->host->host_lock, iflag); 1393 spin_unlock_irqrestore(phba->host->host_lock, iflag);
1394} 1394}
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 5595c612e223..789a12dc986b 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -1019,9 +1019,36 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba,
1019 uint32_t evt) 1019 uint32_t evt)
1020{ 1020{
1021 struct lpfc_iocbq *cmdiocb; 1021 struct lpfc_iocbq *cmdiocb;
1022 LPFC_MBOXQ_t *mb;
1023 LPFC_MBOXQ_t *nextmb;
1024 struct lpfc_dmabuf *mp;
1022 1025
1023 cmdiocb = (struct lpfc_iocbq *) arg; 1026 cmdiocb = (struct lpfc_iocbq *) arg;
1024 1027
1028 /* cleanup any ndlp on mbox q waiting for reglogin cmpl */
1029 if ((mb = phba->sli.mbox_active)) {
1030 if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
1031 (ndlp == (struct lpfc_nodelist *) mb->context2)) {
1032 mb->context2 = NULL;
1033 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1034 }
1035 }
1036
1037 spin_lock_irq(phba->host->host_lock);
1038 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
1039 if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
1040 (ndlp == (struct lpfc_nodelist *) mb->context2)) {
1041 mp = (struct lpfc_dmabuf *) (mb->context1);
1042 if (mp) {
1043 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1044 kfree(mp);
1045 }
1046 list_del(&mb->list);
1047 mempool_free(mb, phba->mbox_mem_pool);
1048 }
1049 }
1050 spin_unlock_irq(phba->host->host_lock);
1051
1025 lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); 1052 lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
1026 return ndlp->nlp_state; 1053 return ndlp->nlp_state;
1027} 1054}
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 28dbd6be72ee..efd1cf638b8c 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -292,13 +292,13 @@ lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
292} 292}
293 293
294static void 294static void
295lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) 295lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_iocbq *rsp_iocb)
296{ 296{
297 struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; 297 struct scsi_cmnd *cmnd = lpfc_cmd->pCmd;
298 struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd; 298 struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd;
299 struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp; 299 struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp;
300 struct lpfc_hba *phba = lpfc_cmd->scsi_hba; 300 struct lpfc_hba *phba = lpfc_cmd->scsi_hba;
301 uint32_t fcpi_parm = lpfc_cmd->cur_iocbq.iocb.un.fcpi.fcpi_parm; 301 uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm;
302 uint32_t resp_info = fcprsp->rspStatus2; 302 uint32_t resp_info = fcprsp->rspStatus2;
303 uint32_t scsi_status = fcprsp->rspStatus3; 303 uint32_t scsi_status = fcprsp->rspStatus3;
304 uint32_t *lp; 304 uint32_t *lp;
@@ -360,6 +360,24 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
360 fcpi_parm, cmnd->cmnd[0], cmnd->underflow); 360 fcpi_parm, cmnd->cmnd[0], cmnd->underflow);
361 361
362 /* 362 /*
363 * If there is an under run check if under run reported by
364 * storage array is same as the under run reported by HBA.
365 * If this is not same, there is a dropped frame.
366 */
367 if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) &&
368 fcpi_parm &&
369 (cmnd->resid != fcpi_parm)) {
370 lpfc_printf_log(phba, KERN_WARNING,
371 LOG_FCP | LOG_FCP_ERROR,
372 "%d:0735 FCP Read Check Error and Underrun "
373 "Data: x%x x%x x%x x%x\n", phba->brd_no,
374 be32_to_cpu(fcpcmd->fcpDl),
375 cmnd->resid,
376 fcpi_parm, cmnd->cmnd[0]);
377 cmnd->resid = cmnd->request_bufflen;
378 host_status = DID_ERROR;
379 }
380 /*
363 * The cmnd->underflow is the minimum number of bytes that must 381 * The cmnd->underflow is the minimum number of bytes that must
364 * be transfered for this command. Provided a sense condition 382 * be transfered for this command. Provided a sense condition
365 * is not present, make sure the actual amount transferred is at 383 * is not present, make sure the actual amount transferred is at
@@ -439,7 +457,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
439 switch (lpfc_cmd->status) { 457 switch (lpfc_cmd->status) {
440 case IOSTAT_FCP_RSP_ERROR: 458 case IOSTAT_FCP_RSP_ERROR:
441 /* Call FCP RSP handler to determine result */ 459 /* Call FCP RSP handler to determine result */
442 lpfc_handle_fcp_err(lpfc_cmd); 460 lpfc_handle_fcp_err(lpfc_cmd,pIocbOut);
443 break; 461 break;
444 case IOSTAT_NPORT_BSY: 462 case IOSTAT_NPORT_BSY:
445 case IOSTAT_FABRIC_BSY: 463 case IOSTAT_FABRIC_BSY:
@@ -673,6 +691,18 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
673 return (1); 691 return (1);
674} 692}
675 693
694static void
695lpfc_tskmgmt_def_cmpl(struct lpfc_hba *phba,
696 struct lpfc_iocbq *cmdiocbq,
697 struct lpfc_iocbq *rspiocbq)
698{
699 struct lpfc_scsi_buf *lpfc_cmd =
700 (struct lpfc_scsi_buf *) cmdiocbq->context1;
701 if (lpfc_cmd)
702 lpfc_release_scsi_buf(phba, lpfc_cmd);
703 return;
704}
705
676static int 706static int
677lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, 707lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
678 unsigned tgt_id, unsigned int lun, 708 unsigned tgt_id, unsigned int lun,
@@ -709,8 +739,9 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
709 &phba->sli.ring[phba->sli.fcp_ring], 739 &phba->sli.ring[phba->sli.fcp_ring],
710 iocbq, iocbqrsp, lpfc_cmd->timeout); 740 iocbq, iocbqrsp, lpfc_cmd->timeout);
711 if (ret != IOCB_SUCCESS) { 741 if (ret != IOCB_SUCCESS) {
742 if (ret == IOCB_TIMEDOUT)
743 iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl;
712 lpfc_cmd->status = IOSTAT_DRIVER_REJECT; 744 lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
713 ret = FAILED;
714 } else { 745 } else {
715 ret = SUCCESS; 746 ret = SUCCESS;
716 lpfc_cmd->result = iocbqrsp->iocb.un.ulpWord[4]; 747 lpfc_cmd->result = iocbqrsp->iocb.un.ulpWord[4];
@@ -977,7 +1008,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
977} 1008}
978 1009
979static int 1010static int
980lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) 1011lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
981{ 1012{
982 struct Scsi_Host *shost = cmnd->device->host; 1013 struct Scsi_Host *shost = cmnd->device->host;
983 struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; 1014 struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
@@ -987,6 +1018,7 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
987 struct lpfc_nodelist *pnode = rdata->pnode; 1018 struct lpfc_nodelist *pnode = rdata->pnode;
988 uint32_t cmd_result = 0, cmd_status = 0; 1019 uint32_t cmd_result = 0, cmd_status = 0;
989 int ret = FAILED; 1020 int ret = FAILED;
1021 int iocb_status = IOCB_SUCCESS;
990 int cnt, loopcnt; 1022 int cnt, loopcnt;
991 1023
992 lpfc_block_error_handler(cmnd); 1024 lpfc_block_error_handler(cmnd);
@@ -998,7 +1030,7 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
998 */ 1030 */
999 while ( 1 ) { 1031 while ( 1 ) {
1000 if (!pnode) 1032 if (!pnode)
1001 return FAILED; 1033 goto out;
1002 1034
1003 if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { 1035 if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
1004 spin_unlock_irq(phba->host->host_lock); 1036 spin_unlock_irq(phba->host->host_lock);
@@ -1016,7 +1048,7 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
1016 } 1048 }
1017 pnode = rdata->pnode; 1049 pnode = rdata->pnode;
1018 if (!pnode) 1050 if (!pnode)
1019 return FAILED; 1051 goto out;
1020 } 1052 }
1021 if (pnode->nlp_state == NLP_STE_MAPPED_NODE) 1053 if (pnode->nlp_state == NLP_STE_MAPPED_NODE)
1022 break; 1054 break;
@@ -1031,7 +1063,7 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
1031 lpfc_cmd->rdata = rdata; 1063 lpfc_cmd->rdata = rdata;
1032 1064
1033 ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun, 1065 ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun,
1034 FCP_LUN_RESET); 1066 FCP_TARGET_RESET);
1035 if (!ret) 1067 if (!ret)
1036 goto out_free_scsi_buf; 1068 goto out_free_scsi_buf;
1037 1069
@@ -1043,16 +1075,21 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
1043 goto out_free_scsi_buf; 1075 goto out_free_scsi_buf;
1044 1076
1045 lpfc_printf_log(phba, KERN_INFO, LOG_FCP, 1077 lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
1046 "%d:0703 Issue LUN Reset to TGT %d LUN %d " 1078 "%d:0703 Issue target reset to TGT %d LUN %d rpi x%x "
1047 "Data: x%x x%x\n", phba->brd_no, cmnd->device->id, 1079 "nlp_flag x%x\n", phba->brd_no, cmnd->device->id,
1048 cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); 1080 cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag);
1049 1081
1050 ret = lpfc_sli_issue_iocb_wait(phba, 1082 iocb_status = lpfc_sli_issue_iocb_wait(phba,
1051 &phba->sli.ring[phba->sli.fcp_ring], 1083 &phba->sli.ring[phba->sli.fcp_ring],
1052 iocbq, iocbqrsp, lpfc_cmd->timeout); 1084 iocbq, iocbqrsp, lpfc_cmd->timeout);
1053 if (ret == IOCB_SUCCESS)
1054 ret = SUCCESS;
1055 1085
1086 if (iocb_status == IOCB_TIMEDOUT)
1087 iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl;
1088
1089 if (iocb_status == IOCB_SUCCESS)
1090 ret = SUCCESS;
1091 else
1092 ret = iocb_status;
1056 1093
1057 cmd_result = iocbqrsp->iocb.un.ulpWord[4]; 1094 cmd_result = iocbqrsp->iocb.un.ulpWord[4];
1058 cmd_status = iocbqrsp->iocb.ulpStatus; 1095 cmd_status = iocbqrsp->iocb.ulpStatus;
@@ -1090,18 +1127,19 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
1090 1127
1091 if (cnt) { 1128 if (cnt) {
1092 lpfc_printf_log(phba, KERN_ERR, LOG_FCP, 1129 lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
1093 "%d:0719 LUN Reset I/O flush failure: cnt x%x\n", 1130 "%d:0719 device reset I/O flush failure: cnt x%x\n",
1094 phba->brd_no, cnt); 1131 phba->brd_no, cnt);
1095 ret = FAILED; 1132 ret = FAILED;
1096 } 1133 }
1097 1134
1098out_free_scsi_buf: 1135out_free_scsi_buf:
1099 lpfc_release_scsi_buf(phba, lpfc_cmd); 1136 if (iocb_status != IOCB_TIMEDOUT) {
1100 1137 lpfc_release_scsi_buf(phba, lpfc_cmd);
1138 }
1101 lpfc_printf_log(phba, KERN_ERR, LOG_FCP, 1139 lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
1102 "%d:0713 SCSI layer issued LUN reset (%d, %d) " 1140 "%d:0713 SCSI layer issued device reset (%d, %d) "
1103 "Data: x%x x%x x%x\n", 1141 "return x%x status x%x result x%x\n",
1104 phba->brd_no, cmnd->device->id,cmnd->device->lun, 1142 phba->brd_no, cmnd->device->id, cmnd->device->lun,
1105 ret, cmd_status, cmd_result); 1143 ret, cmd_status, cmd_result);
1106 1144
1107out: 1145out:
@@ -1110,7 +1148,7 @@ out:
1110} 1148}
1111 1149
1112static int 1150static int
1113lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) 1151lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
1114{ 1152{
1115 struct Scsi_Host *shost = cmnd->device->host; 1153 struct Scsi_Host *shost = cmnd->device->host;
1116 struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; 1154 struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
@@ -1155,13 +1193,17 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
1155 "%d:0700 Bus Reset on target %d failed\n", 1193 "%d:0700 Bus Reset on target %d failed\n",
1156 phba->brd_no, i); 1194 phba->brd_no, i);
1157 err_count++; 1195 err_count++;
1196 break;
1158 } 1197 }
1159 } 1198 }
1160 1199
1200 if (ret != IOCB_TIMEDOUT)
1201 lpfc_release_scsi_buf(phba, lpfc_cmd);
1202
1161 if (err_count == 0) 1203 if (err_count == 0)
1162 ret = SUCCESS; 1204 ret = SUCCESS;
1163 1205 else
1164 lpfc_release_scsi_buf(phba, lpfc_cmd); 1206 ret = FAILED;
1165 1207
1166 /* 1208 /*
1167 * All outstanding txcmplq I/Os should have been aborted by 1209 * All outstanding txcmplq I/Os should have been aborted by
@@ -1302,8 +1344,8 @@ struct scsi_host_template lpfc_template = {
1302 .info = lpfc_info, 1344 .info = lpfc_info,
1303 .queuecommand = lpfc_queuecommand, 1345 .queuecommand = lpfc_queuecommand,
1304 .eh_abort_handler = lpfc_abort_handler, 1346 .eh_abort_handler = lpfc_abort_handler,
1305 .eh_device_reset_handler= lpfc_reset_lun_handler, 1347 .eh_device_reset_handler= lpfc_device_reset_handler,
1306 .eh_bus_reset_handler = lpfc_reset_bus_handler, 1348 .eh_bus_reset_handler = lpfc_bus_reset_handler,
1307 .slave_alloc = lpfc_slave_alloc, 1349 .slave_alloc = lpfc_slave_alloc,
1308 .slave_configure = lpfc_slave_configure, 1350 .slave_configure = lpfc_slave_configure,
1309 .slave_destroy = lpfc_slave_destroy, 1351 .slave_destroy = lpfc_slave_destroy,
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 16825243e603..dba94c68feb1 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -528,6 +528,7 @@ lpfc_sli_wake_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
528 * If pdone_q is empty, the driver thread gave up waiting and 528 * If pdone_q is empty, the driver thread gave up waiting and
529 * continued running. 529 * continued running.
530 */ 530 */
531 pmboxq->mbox_flag |= LPFC_MBX_WAKE;
531 pdone_q = (wait_queue_head_t *) pmboxq->context1; 532 pdone_q = (wait_queue_head_t *) pmboxq->context1;
532 if (pdone_q) 533 if (pdone_q)
533 wake_up_interruptible(pdone_q); 534 wake_up_interruptible(pdone_q);
@@ -538,11 +539,32 @@ void
538lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) 539lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
539{ 540{
540 struct lpfc_dmabuf *mp; 541 struct lpfc_dmabuf *mp;
542 uint16_t rpi;
543 int rc;
544
541 mp = (struct lpfc_dmabuf *) (pmb->context1); 545 mp = (struct lpfc_dmabuf *) (pmb->context1);
546
542 if (mp) { 547 if (mp) {
543 lpfc_mbuf_free(phba, mp->virt, mp->phys); 548 lpfc_mbuf_free(phba, mp->virt, mp->phys);
544 kfree(mp); 549 kfree(mp);
545 } 550 }
551
552 /*
553 * If a REG_LOGIN succeeded after node is destroyed or node
554 * is in re-discovery driver need to cleanup the RPI.
555 */
556 if (!(phba->fc_flag & FC_UNLOADING) &&
557 (pmb->mb.mbxCommand == MBX_REG_LOGIN64) &&
558 (!pmb->mb.mbxStatus)) {
559
560 rpi = pmb->mb.un.varWords[0];
561 lpfc_unreg_login(phba, rpi, pmb);
562 pmb->mbox_cmpl=lpfc_sli_def_mbox_cmpl;
563 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
564 if (rc != MBX_NOT_FINISHED)
565 return;
566 }
567
546 mempool_free( pmb, phba->mbox_mem_pool); 568 mempool_free( pmb, phba->mbox_mem_pool);
547 return; 569 return;
548} 570}
@@ -2862,9 +2884,11 @@ void
2862lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, 2884lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
2863 struct lpfc_iocbq * rspiocb) 2885 struct lpfc_iocbq * rspiocb)
2864{ 2886{
2865 spin_lock_irq(phba->host->host_lock); 2887 unsigned long iflags;
2888
2889 spin_lock_irqsave(phba->host->host_lock, iflags);
2866 lpfc_sli_release_iocbq(phba, cmdiocb); 2890 lpfc_sli_release_iocbq(phba, cmdiocb);
2867 spin_unlock_irq(phba->host->host_lock); 2891 spin_unlock_irqrestore(phba->host->host_lock, iflags);
2868 return; 2892 return;
2869} 2893}
2870 2894
@@ -2987,22 +3011,22 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
2987 timeout_req); 3011 timeout_req);
2988 spin_lock_irq(phba->host->host_lock); 3012 spin_lock_irq(phba->host->host_lock);
2989 3013
2990 if (timeleft == 0) { 3014 if (piocb->iocb_flag & LPFC_IO_WAKE) {
3015 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
3016 "%d:0331 IOCB wake signaled\n",
3017 phba->brd_no);
3018 } else if (timeleft == 0) {
2991 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 3019 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
2992 "%d:0338 IOCB wait timeout error - no " 3020 "%d:0338 IOCB wait timeout error - no "
2993 "wake response Data x%x\n", 3021 "wake response Data x%x\n",
2994 phba->brd_no, timeout); 3022 phba->brd_no, timeout);
2995 retval = IOCB_TIMEDOUT; 3023 retval = IOCB_TIMEDOUT;
2996 } else if (!(piocb->iocb_flag & LPFC_IO_WAKE)) { 3024 } else {
2997 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 3025 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
2998 "%d:0330 IOCB wake NOT set, " 3026 "%d:0330 IOCB wake NOT set, "
2999 "Data x%x x%lx\n", phba->brd_no, 3027 "Data x%x x%lx\n", phba->brd_no,
3000 timeout, (timeleft / jiffies)); 3028 timeout, (timeleft / jiffies));
3001 retval = IOCB_TIMEDOUT; 3029 retval = IOCB_TIMEDOUT;
3002 } else {
3003 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
3004 "%d:0331 IOCB wake signaled\n",
3005 phba->brd_no);
3006 } 3030 }
3007 } else { 3031 } else {
3008 lpfc_printf_log(phba, KERN_INFO, LOG_SLI, 3032 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
@@ -3031,8 +3055,6 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
3031 uint32_t timeout) 3055 uint32_t timeout)
3032{ 3056{
3033 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); 3057 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
3034 DECLARE_WAITQUEUE(wq_entry, current);
3035 uint32_t timeleft = 0;
3036 int retval; 3058 int retval;
3037 3059
3038 /* The caller must leave context1 empty. */ 3060 /* The caller must leave context1 empty. */
@@ -3045,27 +3067,25 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
3045 /* setup context field to pass wait_queue pointer to wake function */ 3067 /* setup context field to pass wait_queue pointer to wake function */
3046 pmboxq->context1 = &done_q; 3068 pmboxq->context1 = &done_q;
3047 3069
3048 /* start to sleep before we wait, to avoid races */
3049 set_current_state(TASK_INTERRUPTIBLE);
3050 add_wait_queue(&done_q, &wq_entry);
3051
3052 /* now issue the command */ 3070 /* now issue the command */
3053 retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); 3071 retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
3054 3072
3055 if (retval == MBX_BUSY || retval == MBX_SUCCESS) { 3073 if (retval == MBX_BUSY || retval == MBX_SUCCESS) {
3056 timeleft = schedule_timeout(timeout * HZ); 3074 wait_event_interruptible_timeout(done_q,
3075 pmboxq->mbox_flag & LPFC_MBX_WAKE,
3076 timeout * HZ);
3077
3057 pmboxq->context1 = NULL; 3078 pmboxq->context1 = NULL;
3058 /* if schedule_timeout returns 0, we timed out and were not 3079 /*
3059 woken up */ 3080 * if LPFC_MBX_WAKE flag is set the mailbox is completed
3060 if ((timeleft == 0) || signal_pending(current)) 3081 * else do not free the resources.
3061 retval = MBX_TIMEOUT; 3082 */
3062 else 3083 if (pmboxq->mbox_flag & LPFC_MBX_WAKE)
3063 retval = MBX_SUCCESS; 3084 retval = MBX_SUCCESS;
3085 else
3086 retval = MBX_TIMEOUT;
3064 } 3087 }
3065 3088
3066
3067 set_current_state(TASK_RUNNING);
3068 remove_wait_queue(&done_q, &wq_entry);
3069 return retval; 3089 return retval;
3070} 3090}
3071 3091
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 10dd5a9ddfd3..eb6a689e52e1 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -68,6 +68,8 @@ struct lpfc_iocbq {
68#define IOCB_ERROR 2 68#define IOCB_ERROR 2
69#define IOCB_TIMEDOUT 3 69#define IOCB_TIMEDOUT 3
70 70
71#define LPFC_MBX_WAKE 1
72
71typedef struct lpfcMboxq { 73typedef struct lpfcMboxq {
72 /* MBOXQs are used in single linked lists */ 74 /* MBOXQs are used in single linked lists */
73 struct list_head list; /* ptr to next mailbox command */ 75 struct list_head list; /* ptr to next mailbox command */
@@ -76,6 +78,7 @@ typedef struct lpfcMboxq {
76 void *context2; /* caller context information */ 78 void *context2; /* caller context information */
77 79
78 void (*mbox_cmpl) (struct lpfc_hba *, struct lpfcMboxq *); 80 void (*mbox_cmpl) (struct lpfc_hba *, struct lpfcMboxq *);
81 uint8_t mbox_flag;
79 82
80} LPFC_MBOXQ_t; 83} LPFC_MBOXQ_t;
81 84