diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mbox.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 7465fe746fe9..34eeb086a667 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -77,6 +77,38 @@ lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * lpfc_dump_mem: Prepare a mailbox command for retrieving wakeup params. | ||
81 | * @phba: pointer to lpfc hba data structure. | ||
82 | * @pmb: pointer to the driver internal queue element for mailbox command. | ||
83 | * This function create a dump memory mailbox command to dump wake up | ||
84 | * parameters. | ||
85 | */ | ||
86 | void | ||
87 | lpfc_dump_wakeup_param(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | ||
88 | { | ||
89 | MAILBOX_t *mb; | ||
90 | void *ctx; | ||
91 | |||
92 | mb = &pmb->mb; | ||
93 | /* Save context so that we can restore after memset */ | ||
94 | ctx = pmb->context2; | ||
95 | |||
96 | /* Setup to dump VPD region */ | ||
97 | memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); | ||
98 | mb->mbxCommand = MBX_DUMP_MEMORY; | ||
99 | mb->mbxOwner = OWN_HOST; | ||
100 | mb->un.varDmp.cv = 1; | ||
101 | mb->un.varDmp.type = DMP_NV_PARAMS; | ||
102 | mb->un.varDmp.entry_index = 0; | ||
103 | mb->un.varDmp.region_id = WAKE_UP_PARMS_REGION_ID; | ||
104 | mb->un.varDmp.word_cnt = WAKE_UP_PARMS_WORD_SIZE; | ||
105 | mb->un.varDmp.co = 0; | ||
106 | mb->un.varDmp.resp_offset = 0; | ||
107 | pmb->context2 = ctx; | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | /** | ||
80 | * lpfc_read_nv: Prepare a mailbox command for reading HBA's NVRAM param. | 112 | * lpfc_read_nv: Prepare a mailbox command for reading HBA's NVRAM param. |
81 | * @phba: pointer to lpfc hba data structure. | 113 | * @phba: pointer to lpfc hba data structure. |
82 | * @pmb: pointer to the driver internal queue element for mailbox command. | 114 | * @pmb: pointer to the driver internal queue element for mailbox command. |
@@ -1061,9 +1093,14 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1061 | mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr); | 1093 | mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr); |
1062 | mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr); | 1094 | mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr); |
1063 | 1095 | ||
1096 | /* Always Host Group Pointer is in SLIM */ | ||
1097 | mb->un.varCfgPort.hps = 1; | ||
1098 | |||
1064 | /* If HBA supports SLI=3 ask for it */ | 1099 | /* If HBA supports SLI=3 ask for it */ |
1065 | 1100 | ||
1066 | if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) { | 1101 | if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) { |
1102 | if (phba->cfg_enable_bg) | ||
1103 | mb->un.varCfgPort.cbg = 1; /* configure BlockGuard */ | ||
1067 | mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ | 1104 | mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ |
1068 | mb->un.varCfgPort.ccrp = 1; /* Command Ring Polling */ | 1105 | mb->un.varCfgPort.ccrp = 1; /* Command Ring Polling */ |
1069 | mb->un.varCfgPort.cinb = 1; /* Interrupt Notification Block */ | 1106 | mb->un.varCfgPort.cinb = 1; /* Interrupt Notification Block */ |
@@ -1163,16 +1200,11 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1163 | sizeof(*phba->host_gp)); | 1200 | sizeof(*phba->host_gp)); |
1164 | } | 1201 | } |
1165 | 1202 | ||
1166 | /* Setup Port Group ring pointer */ | 1203 | /* Setup Port Group offset */ |
1167 | if (phba->sli3_options & LPFC_SLI3_INB_ENABLED) { | 1204 | if (phba->sli_rev == 3) |
1168 | pgp_offset = offsetof(struct lpfc_sli2_slim, | ||
1169 | mbx.us.s3_inb_pgp.port); | ||
1170 | phba->hbq_get = phba->mbox->us.s3_inb_pgp.hbq_get; | ||
1171 | } else if (phba->sli_rev == 3) { | ||
1172 | pgp_offset = offsetof(struct lpfc_sli2_slim, | 1205 | pgp_offset = offsetof(struct lpfc_sli2_slim, |
1173 | mbx.us.s3_pgp.port); | 1206 | mbx.us.s3_pgp.port); |
1174 | phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get; | 1207 | else |
1175 | } else | ||
1176 | pgp_offset = offsetof(struct lpfc_sli2_slim, mbx.us.s2.port); | 1208 | pgp_offset = offsetof(struct lpfc_sli2_slim, mbx.us.s2.port); |
1177 | pdma_addr = phba->slim2p.phys + pgp_offset; | 1209 | pdma_addr = phba->slim2p.phys + pgp_offset; |
1178 | phba->pcb->pgpAddrHigh = putPaddrHigh(pdma_addr); | 1210 | phba->pcb->pgpAddrHigh = putPaddrHigh(pdma_addr); |
@@ -1285,10 +1317,12 @@ lpfc_mbox_get(struct lpfc_hba * phba) | |||
1285 | void | 1317 | void |
1286 | lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) | 1318 | lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) |
1287 | { | 1319 | { |
1320 | unsigned long iflag; | ||
1321 | |||
1288 | /* This function expects to be called from interrupt context */ | 1322 | /* This function expects to be called from interrupt context */ |
1289 | spin_lock(&phba->hbalock); | 1323 | spin_lock_irqsave(&phba->hbalock, iflag); |
1290 | list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl); | 1324 | list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl); |
1291 | spin_unlock(&phba->hbalock); | 1325 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1292 | return; | 1326 | return; |
1293 | } | 1327 | } |
1294 | 1328 | ||