diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_ct.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 74 |
1 files changed, 52 insertions, 22 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 7f427f9c4688..b65ee57af53e 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -260,8 +260,10 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, | |||
260 | icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL; | 260 | icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL; |
261 | icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP; | 261 | icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP; |
262 | 262 | ||
263 | if (!tmo) | 263 | if (!tmo) { |
264 | tmo = (2 * phba->fc_ratov) + 1; | 264 | /* FC spec states we need 3 * ratov for CT requests */ |
265 | tmo = (3 * phba->fc_ratov); | ||
266 | } | ||
265 | icmd->ulpTimeout = tmo; | 267 | icmd->ulpTimeout = tmo; |
266 | icmd->ulpBdeCount = 1; | 268 | icmd->ulpBdeCount = 1; |
267 | icmd->ulpLe = 1; | 269 | icmd->ulpLe = 1; |
@@ -321,6 +323,7 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) | |||
321 | struct lpfc_sli_ct_request *Response = | 323 | struct lpfc_sli_ct_request *Response = |
322 | (struct lpfc_sli_ct_request *) mp->virt; | 324 | (struct lpfc_sli_ct_request *) mp->virt; |
323 | struct lpfc_nodelist *ndlp = NULL; | 325 | struct lpfc_nodelist *ndlp = NULL; |
326 | struct lpfc_nodelist *next_ndlp; | ||
324 | struct lpfc_dmabuf *mlast, *next_mp; | 327 | struct lpfc_dmabuf *mlast, *next_mp; |
325 | uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; | 328 | uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; |
326 | uint32_t Did; | 329 | uint32_t Did; |
@@ -389,8 +392,36 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) | |||
389 | nsout1: | 392 | nsout1: |
390 | list_del(&head); | 393 | list_del(&head); |
391 | 394 | ||
392 | /* Here we are finished in the case RSCN */ | 395 | /* |
396 | * The driver has cycled through all Nports in the RSCN payload. | ||
397 | * Complete the handling by cleaning up and marking the | ||
398 | * current driver state. | ||
399 | */ | ||
393 | if (phba->hba_state == LPFC_HBA_READY) { | 400 | if (phba->hba_state == LPFC_HBA_READY) { |
401 | |||
402 | /* | ||
403 | * Switch ports that connect a loop of multiple targets need | ||
404 | * special consideration. The driver wants to unregister the | ||
405 | * rpi only on the target that was pulled from the loop. On | ||
406 | * RSCN, the driver wants to rediscover an NPort only if the | ||
407 | * driver flagged it as NLP_NPR_2B_DISC. Provided adisc is | ||
408 | * not enabled and the NPort is not capable of retransmissions | ||
409 | * (FC Tape) prevent timing races with the scsi error handler by | ||
410 | * unregistering the Nport's RPI. This action causes all | ||
411 | * outstanding IO to flush back to the midlayer. | ||
412 | */ | ||
413 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, | ||
414 | nlp_listp) { | ||
415 | if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC) && | ||
416 | (lpfc_rscn_payload_check(phba, ndlp->nlp_DID))) { | ||
417 | if ((phba->cfg_use_adisc == 0) && | ||
418 | !(ndlp->nlp_fcp_info & | ||
419 | NLP_FCP_2_DEVICE)) { | ||
420 | lpfc_unreg_rpi(phba, ndlp); | ||
421 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | ||
422 | } | ||
423 | } | ||
424 | } | ||
394 | lpfc_els_flush_rscn(phba); | 425 | lpfc_els_flush_rscn(phba); |
395 | spin_lock_irq(phba->host->host_lock); | 426 | spin_lock_irq(phba->host->host_lock); |
396 | phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */ | 427 | phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */ |
@@ -449,6 +480,11 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
449 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | 480 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; |
450 | if (CTrsp->CommandResponse.bits.CmdRsp == | 481 | if (CTrsp->CommandResponse.bits.CmdRsp == |
451 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { | 482 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { |
483 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | ||
484 | "%d:0239 NameServer Rsp " | ||
485 | "Data: x%x\n", | ||
486 | phba->brd_no, | ||
487 | phba->fc_flag); | ||
452 | lpfc_ns_rsp(phba, outp, | 488 | lpfc_ns_rsp(phba, outp, |
453 | (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); | 489 | (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); |
454 | } else if (CTrsp->CommandResponse.bits.CmdRsp == | 490 | } else if (CTrsp->CommandResponse.bits.CmdRsp == |
@@ -978,19 +1014,19 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
978 | ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); | 1014 | ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); |
979 | ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED); | 1015 | ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED); |
980 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); | 1016 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); |
981 | if (FC_JEDEC_ID(vp->rev.biuRev) == VIPER_JEDEC_ID) | 1017 | |
1018 | ae->un.SupportSpeed = 0; | ||
1019 | if (phba->lmt & LMT_10Gb) | ||
982 | ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT; | 1020 | ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT; |
983 | else if (FC_JEDEC_ID(vp->rev.biuRev) == HELIOS_JEDEC_ID) | 1021 | if (phba->lmt & LMT_8Gb) |
984 | ae->un.SupportSpeed = HBA_PORTSPEED_4GBIT; | 1022 | ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT; |
985 | else if ((FC_JEDEC_ID(vp->rev.biuRev) == | 1023 | if (phba->lmt & LMT_4Gb) |
986 | CENTAUR_2G_JEDEC_ID) | 1024 | ae->un.SupportSpeed |= HBA_PORTSPEED_4GBIT; |
987 | || (FC_JEDEC_ID(vp->rev.biuRev) == | 1025 | if (phba->lmt & LMT_2Gb) |
988 | PEGASUS_JEDEC_ID) | 1026 | ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT; |
989 | || (FC_JEDEC_ID(vp->rev.biuRev) == | 1027 | if (phba->lmt & LMT_1Gb) |
990 | THOR_JEDEC_ID)) | 1028 | ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT; |
991 | ae->un.SupportSpeed = HBA_PORTSPEED_2GBIT; | 1029 | |
992 | else | ||
993 | ae->un.SupportSpeed = HBA_PORTSPEED_1GBIT; | ||
994 | pab->ab.EntryCnt++; | 1030 | pab->ab.EntryCnt++; |
995 | size += FOURBYTES + 4; | 1031 | size += FOURBYTES + 4; |
996 | 1032 | ||
@@ -1130,11 +1166,6 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba) | |||
1130 | { | 1166 | { |
1131 | struct lpfc_nodelist *ndlp; | 1167 | struct lpfc_nodelist *ndlp; |
1132 | 1168 | ||
1133 | spin_lock_irq(phba->host->host_lock); | ||
1134 | if (!(phba->work_hba_events & WORKER_FDMI_TMO)) { | ||
1135 | spin_unlock_irq(phba->host->host_lock); | ||
1136 | return; | ||
1137 | } | ||
1138 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID); | 1169 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID); |
1139 | if (ndlp) { | 1170 | if (ndlp) { |
1140 | if (system_utsname.nodename[0] != '\0') { | 1171 | if (system_utsname.nodename[0] != '\0') { |
@@ -1143,7 +1174,6 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba) | |||
1143 | mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); | 1174 | mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); |
1144 | } | 1175 | } |
1145 | } | 1176 | } |
1146 | spin_unlock_irq(phba->host->host_lock); | ||
1147 | return; | 1177 | return; |
1148 | } | 1178 | } |
1149 | 1179 | ||