diff options
author | James Smart <James.Smart@Emulex.Com> | 2006-04-15 11:53:05 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-04-19 20:48:58 -0400 |
commit | 82d9a2a2900b17223117dc10b56503acc678c337 (patch) | |
tree | 757f398e585a6bbe64ebedae98b0957cab770279 /drivers/scsi | |
parent | 4b0b91d4611aba058c16440f9841906853741330 (diff) |
[SCSI] lpfc 8.1.5 : Fixed FC protocol violation in handling of PRLO.
Fixed FC protocol violation in handling of PRLO.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 18 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 32 |
3 files changed, 38 insertions, 14 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 45abc76ff898..e3d8b7f47f12 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -1913,6 +1913,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1913 | uint8_t *pcmd; | 1913 | uint8_t *pcmd; |
1914 | uint16_t cmdsize; | 1914 | uint16_t cmdsize; |
1915 | int rc; | 1915 | int rc; |
1916 | ELS_PKT *els_pkt_ptr; | ||
1916 | 1917 | ||
1917 | psli = &phba->sli; | 1918 | psli = &phba->sli; |
1918 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 1919 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
@@ -1951,6 +1952,23 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1951 | pcmd += sizeof (uint32_t); | 1952 | pcmd += sizeof (uint32_t); |
1952 | memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); | 1953 | memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); |
1953 | break; | 1954 | break; |
1955 | case ELS_CMD_PRLO: | ||
1956 | cmdsize = sizeof (uint32_t) + sizeof (PRLO); | ||
1957 | elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | ||
1958 | ndlp, ndlp->nlp_DID, ELS_CMD_PRLO); | ||
1959 | if (!elsiocb) | ||
1960 | return 1; | ||
1961 | |||
1962 | icmd = &elsiocb->iocb; | ||
1963 | icmd->ulpContext = oldcmd->ulpContext; /* Xri */ | ||
1964 | pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | ||
1965 | |||
1966 | memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt, | ||
1967 | sizeof (uint32_t) + sizeof (PRLO)); | ||
1968 | *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC; | ||
1969 | els_pkt_ptr = (ELS_PKT *) pcmd; | ||
1970 | els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED; | ||
1971 | break; | ||
1954 | default: | 1972 | default: |
1955 | return 1; | 1973 | return 1; |
1956 | } | 1974 | } |
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index b12569eefd1c..eedf98801366 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -449,6 +449,7 @@ struct serv_parm { /* Structure is in Big Endian format */ | |||
449 | #define ELS_CMD_RRQ 0x12000000 | 449 | #define ELS_CMD_RRQ 0x12000000 |
450 | #define ELS_CMD_PRLI 0x20100014 | 450 | #define ELS_CMD_PRLI 0x20100014 |
451 | #define ELS_CMD_PRLO 0x21100014 | 451 | #define ELS_CMD_PRLO 0x21100014 |
452 | #define ELS_CMD_PRLO_ACC 0x02100014 | ||
452 | #define ELS_CMD_PDISC 0x50000000 | 453 | #define ELS_CMD_PDISC 0x50000000 |
453 | #define ELS_CMD_FDISC 0x51000000 | 454 | #define ELS_CMD_FDISC 0x51000000 |
454 | #define ELS_CMD_ADISC 0x52000000 | 455 | #define ELS_CMD_ADISC 0x52000000 |
@@ -484,6 +485,7 @@ struct serv_parm { /* Structure is in Big Endian format */ | |||
484 | #define ELS_CMD_RRQ 0x12 | 485 | #define ELS_CMD_RRQ 0x12 |
485 | #define ELS_CMD_PRLI 0x14001020 | 486 | #define ELS_CMD_PRLI 0x14001020 |
486 | #define ELS_CMD_PRLO 0x14001021 | 487 | #define ELS_CMD_PRLO 0x14001021 |
488 | #define ELS_CMD_PRLO_ACC 0x14001002 | ||
487 | #define ELS_CMD_PDISC 0x50 | 489 | #define ELS_CMD_PDISC 0x50 |
488 | #define ELS_CMD_FDISC 0x51 | 490 | #define ELS_CMD_FDISC 0x51 |
489 | #define ELS_CMD_ADISC 0x52 | 491 | #define ELS_CMD_ADISC 0x52 |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index adebe626a23f..27d60ad897cd 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -465,14 +465,18 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, | |||
465 | static int | 465 | static int |
466 | lpfc_rcv_logo(struct lpfc_hba * phba, | 466 | lpfc_rcv_logo(struct lpfc_hba * phba, |
467 | struct lpfc_nodelist * ndlp, | 467 | struct lpfc_nodelist * ndlp, |
468 | struct lpfc_iocbq *cmdiocb) | 468 | struct lpfc_iocbq *cmdiocb, |
469 | uint32_t els_cmd) | ||
469 | { | 470 | { |
470 | /* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */ | 471 | /* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */ |
471 | /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary | 472 | /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary |
472 | * PLOGIs during LOGO storms from a device. | 473 | * PLOGIs during LOGO storms from a device. |
473 | */ | 474 | */ |
474 | ndlp->nlp_flag |= NLP_LOGO_ACC; | 475 | ndlp->nlp_flag |= NLP_LOGO_ACC; |
475 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 476 | if (els_cmd == ELS_CMD_PRLO) |
477 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); | ||
478 | else | ||
479 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | ||
476 | 480 | ||
477 | if (!(ndlp->nlp_type & NLP_FABRIC) || | 481 | if (!(ndlp->nlp_type & NLP_FABRIC) || |
478 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { | 482 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { |
@@ -681,7 +685,7 @@ lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba, | |||
681 | /* software abort outstanding PLOGI */ | 685 | /* software abort outstanding PLOGI */ |
682 | lpfc_els_abort(phba, ndlp, 1); | 686 | lpfc_els_abort(phba, ndlp, 1); |
683 | 687 | ||
684 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 688 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); |
685 | return ndlp->nlp_state; | 689 | return ndlp->nlp_state; |
686 | } | 690 | } |
687 | 691 | ||
@@ -907,7 +911,7 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, | |||
907 | /* software abort outstanding ADISC */ | 911 | /* software abort outstanding ADISC */ |
908 | lpfc_els_abort(phba, ndlp, 0); | 912 | lpfc_els_abort(phba, ndlp, 0); |
909 | 913 | ||
910 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 914 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); |
911 | return ndlp->nlp_state; | 915 | return ndlp->nlp_state; |
912 | } | 916 | } |
913 | 917 | ||
@@ -934,7 +938,7 @@ lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba, | |||
934 | cmdiocb = (struct lpfc_iocbq *) arg; | 938 | cmdiocb = (struct lpfc_iocbq *) arg; |
935 | 939 | ||
936 | /* Treat like rcv logo */ | 940 | /* Treat like rcv logo */ |
937 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 941 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO); |
938 | return ndlp->nlp_state; | 942 | return ndlp->nlp_state; |
939 | } | 943 | } |
940 | 944 | ||
@@ -1056,7 +1060,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, | |||
1056 | 1060 | ||
1057 | cmdiocb = (struct lpfc_iocbq *) arg; | 1061 | cmdiocb = (struct lpfc_iocbq *) arg; |
1058 | 1062 | ||
1059 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1063 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); |
1060 | return ndlp->nlp_state; | 1064 | return ndlp->nlp_state; |
1061 | } | 1065 | } |
1062 | 1066 | ||
@@ -1081,7 +1085,7 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba, | |||
1081 | struct lpfc_iocbq *cmdiocb; | 1085 | struct lpfc_iocbq *cmdiocb; |
1082 | 1086 | ||
1083 | cmdiocb = (struct lpfc_iocbq *) arg; | 1087 | cmdiocb = (struct lpfc_iocbq *) arg; |
1084 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1088 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
1085 | return ndlp->nlp_state; | 1089 | return ndlp->nlp_state; |
1086 | } | 1090 | } |
1087 | 1091 | ||
@@ -1200,7 +1204,7 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba, | |||
1200 | /* Software abort outstanding PRLI before sending acc */ | 1204 | /* Software abort outstanding PRLI before sending acc */ |
1201 | lpfc_els_abort(phba, ndlp, 1); | 1205 | lpfc_els_abort(phba, ndlp, 1); |
1202 | 1206 | ||
1203 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1207 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); |
1204 | return ndlp->nlp_state; | 1208 | return ndlp->nlp_state; |
1205 | } | 1209 | } |
1206 | 1210 | ||
@@ -1228,7 +1232,7 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba, | |||
1228 | struct lpfc_iocbq *cmdiocb; | 1232 | struct lpfc_iocbq *cmdiocb; |
1229 | 1233 | ||
1230 | cmdiocb = (struct lpfc_iocbq *) arg; | 1234 | cmdiocb = (struct lpfc_iocbq *) arg; |
1231 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1235 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
1232 | return ndlp->nlp_state; | 1236 | return ndlp->nlp_state; |
1233 | } | 1237 | } |
1234 | 1238 | ||
@@ -1371,7 +1375,7 @@ lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba, | |||
1371 | 1375 | ||
1372 | cmdiocb = (struct lpfc_iocbq *) arg; | 1376 | cmdiocb = (struct lpfc_iocbq *) arg; |
1373 | 1377 | ||
1374 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1378 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); |
1375 | return ndlp->nlp_state; | 1379 | return ndlp->nlp_state; |
1376 | } | 1380 | } |
1377 | 1381 | ||
@@ -1395,7 +1399,7 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba, | |||
1395 | 1399 | ||
1396 | cmdiocb = (struct lpfc_iocbq *) arg; | 1400 | cmdiocb = (struct lpfc_iocbq *) arg; |
1397 | 1401 | ||
1398 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1402 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
1399 | return ndlp->nlp_state; | 1403 | return ndlp->nlp_state; |
1400 | } | 1404 | } |
1401 | 1405 | ||
@@ -1444,7 +1448,7 @@ lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba, | |||
1444 | 1448 | ||
1445 | cmdiocb = (struct lpfc_iocbq *) arg; | 1449 | cmdiocb = (struct lpfc_iocbq *) arg; |
1446 | 1450 | ||
1447 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1451 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); |
1448 | return ndlp->nlp_state; | 1452 | return ndlp->nlp_state; |
1449 | } | 1453 | } |
1450 | 1454 | ||
@@ -1476,7 +1480,7 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba, | |||
1476 | spin_unlock_irq(phba->host->host_lock); | 1480 | spin_unlock_irq(phba->host->host_lock); |
1477 | 1481 | ||
1478 | /* Treat like rcv logo */ | 1482 | /* Treat like rcv logo */ |
1479 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1483 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO); |
1480 | return ndlp->nlp_state; | 1484 | return ndlp->nlp_state; |
1481 | } | 1485 | } |
1482 | 1486 | ||
@@ -1571,7 +1575,7 @@ lpfc_rcv_logo_npr_node(struct lpfc_hba * phba, | |||
1571 | 1575 | ||
1572 | cmdiocb = (struct lpfc_iocbq *) arg; | 1576 | cmdiocb = (struct lpfc_iocbq *) arg; |
1573 | 1577 | ||
1574 | lpfc_rcv_logo(phba, ndlp, cmdiocb); | 1578 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); |
1575 | return ndlp->nlp_state; | 1579 | return ndlp->nlp_state; |
1576 | } | 1580 | } |
1577 | 1581 | ||