aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-02-26 14:15:57 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-03-03 08:40:09 -0500
commit0c9ab6f5cb28199ef5de84874d135ed44f64d92b (patch)
tree51140c5edce1250e0c06b5a38b540b533b092247 /drivers/scsi/lpfc/lpfc_sli.c
parentfc2b989be9190f3311a5ae41289828e24897a20e (diff)
[SCSI] lpfc 8.3.10: Added round robin FCF failover
- Added round robin FCF failover on initial or FCF rediscovery FLOGI failure. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c218
1 files changed, 204 insertions, 14 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index bb6a4426d469..fe6660ca6452 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -11996,15 +11996,19 @@ lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *phba,
11996} 11996}
11997 11997
11998/** 11998/**
11999 * lpfc_sli4_read_fcf_record - Read the driver's default FCF Record. 11999 * lpfc_sli4_fcf_scan_read_fcf_rec - Read hba fcf record for fcf scan.
12000 * @phba: pointer to lpfc hba data structure. 12000 * @phba: pointer to lpfc hba data structure.
12001 * @fcf_index: FCF table entry offset. 12001 * @fcf_index: FCF table entry offset.
12002 * 12002 *
12003 * This routine is invoked to read up to @fcf_num of FCF record from the 12003 * This routine is invoked to scan the entire FCF table by reading FCF
12004 * device starting with the given @fcf_index. 12004 * record and processing it one at a time starting from the @fcf_index
12005 * for initial FCF discovery or fast FCF failover rediscovery.
12006 *
12007 * Return 0 if the mailbox command is submitted sucessfully, none 0
12008 * otherwise.
12005 **/ 12009 **/
12006int 12010int
12007lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) 12011lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
12008{ 12012{
12009 int rc = 0, error; 12013 int rc = 0, error;
12010 LPFC_MBOXQ_t *mboxq; 12014 LPFC_MBOXQ_t *mboxq;
@@ -12016,17 +12020,17 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
12016 "2000 Failed to allocate mbox for " 12020 "2000 Failed to allocate mbox for "
12017 "READ_FCF cmd\n"); 12021 "READ_FCF cmd\n");
12018 error = -ENOMEM; 12022 error = -ENOMEM;
12019 goto fail_fcfscan; 12023 goto fail_fcf_scan;
12020 } 12024 }
12021 /* Construct the read FCF record mailbox command */ 12025 /* Construct the read FCF record mailbox command */
12022 rc = lpfc_sli4_mbx_read_fcf_record(phba, mboxq, fcf_index); 12026 rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
12023 if (rc) { 12027 if (rc) {
12024 error = -EINVAL; 12028 error = -EINVAL;
12025 goto fail_fcfscan; 12029 goto fail_fcf_scan;
12026 } 12030 }
12027 /* Issue the mailbox command asynchronously */ 12031 /* Issue the mailbox command asynchronously */
12028 mboxq->vport = phba->pport; 12032 mboxq->vport = phba->pport;
12029 mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record; 12033 mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_scan_read_fcf_rec;
12030 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); 12034 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
12031 if (rc == MBX_NOT_FINISHED) 12035 if (rc == MBX_NOT_FINISHED)
12032 error = -EIO; 12036 error = -EIO;
@@ -12034,9 +12038,13 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
12034 spin_lock_irq(&phba->hbalock); 12038 spin_lock_irq(&phba->hbalock);
12035 phba->hba_flag |= FCF_DISC_INPROGRESS; 12039 phba->hba_flag |= FCF_DISC_INPROGRESS;
12036 spin_unlock_irq(&phba->hbalock); 12040 spin_unlock_irq(&phba->hbalock);
12041 /* Reset FCF round robin index bmask for new scan */
12042 if (fcf_index == LPFC_FCOE_FCF_GET_FIRST)
12043 memset(phba->fcf.fcf_rr_bmask, 0,
12044 sizeof(*phba->fcf.fcf_rr_bmask));
12037 error = 0; 12045 error = 0;
12038 } 12046 }
12039fail_fcfscan: 12047fail_fcf_scan:
12040 if (error) { 12048 if (error) {
12041 if (mboxq) 12049 if (mboxq)
12042 lpfc_sli4_mbox_cmd_free(phba, mboxq); 12050 lpfc_sli4_mbox_cmd_free(phba, mboxq);
@@ -12049,6 +12057,181 @@ fail_fcfscan:
12049} 12057}
12050 12058
12051/** 12059/**
12060 * lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for round robin fcf.
12061 * @phba: pointer to lpfc hba data structure.
12062 * @fcf_index: FCF table entry offset.
12063 *
12064 * This routine is invoked to read an FCF record indicated by @fcf_index
12065 * and to use it for FLOGI round robin FCF failover.
12066 *
12067 * Return 0 if the mailbox command is submitted sucessfully, none 0
12068 * otherwise.
12069 **/
12070int
12071lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
12072{
12073 int rc = 0, error;
12074 LPFC_MBOXQ_t *mboxq;
12075
12076 mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
12077 if (!mboxq) {
12078 lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT,
12079 "2763 Failed to allocate mbox for "
12080 "READ_FCF cmd\n");
12081 error = -ENOMEM;
12082 goto fail_fcf_read;
12083 }
12084 /* Construct the read FCF record mailbox command */
12085 rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
12086 if (rc) {
12087 error = -EINVAL;
12088 goto fail_fcf_read;
12089 }
12090 /* Issue the mailbox command asynchronously */
12091 mboxq->vport = phba->pport;
12092 mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_rr_read_fcf_rec;
12093 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
12094 if (rc == MBX_NOT_FINISHED)
12095 error = -EIO;
12096 else
12097 error = 0;
12098
12099fail_fcf_read:
12100 if (error && mboxq)
12101 lpfc_sli4_mbox_cmd_free(phba, mboxq);
12102 return error;
12103}
12104
12105/**
12106 * lpfc_sli4_read_fcf_rec - Read hba fcf record for update eligible fcf bmask.
12107 * @phba: pointer to lpfc hba data structure.
12108 * @fcf_index: FCF table entry offset.
12109 *
12110 * This routine is invoked to read an FCF record indicated by @fcf_index to
12111 * determine whether it's eligible for FLOGI round robin failover list.
12112 *
12113 * Return 0 if the mailbox command is submitted sucessfully, none 0
12114 * otherwise.
12115 **/
12116int
12117lpfc_sli4_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
12118{
12119 int rc = 0, error;
12120 LPFC_MBOXQ_t *mboxq;
12121
12122 mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
12123 if (!mboxq) {
12124 lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT,
12125 "2758 Failed to allocate mbox for "
12126 "READ_FCF cmd\n");
12127 error = -ENOMEM;
12128 goto fail_fcf_read;
12129 }
12130 /* Construct the read FCF record mailbox command */
12131 rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
12132 if (rc) {
12133 error = -EINVAL;
12134 goto fail_fcf_read;
12135 }
12136 /* Issue the mailbox command asynchronously */
12137 mboxq->vport = phba->pport;
12138 mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_rec;
12139 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
12140 if (rc == MBX_NOT_FINISHED)
12141 error = -EIO;
12142 else
12143 error = 0;
12144
12145fail_fcf_read:
12146 if (error && mboxq)
12147 lpfc_sli4_mbox_cmd_free(phba, mboxq);
12148 return error;
12149}
12150
12151/**
12152 * lpfc_sli4_fcf_rr_next_index_get - Get next eligible fcf record index
12153 * @phba: pointer to lpfc hba data structure.
12154 *
12155 * This routine is to get the next eligible FCF record index in a round
12156 * robin fashion. If the next eligible FCF record index equals to the
12157 * initial round robin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF)
12158 * shall be returned, otherwise, the next eligible FCF record's index
12159 * shall be returned.
12160 **/
12161uint16_t
12162lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba)
12163{
12164 uint16_t next_fcf_index;
12165
12166 /* Search from the currently registered FCF index */
12167 next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask,
12168 LPFC_SLI4_FCF_TBL_INDX_MAX,
12169 phba->fcf.current_rec.fcf_indx);
12170 /* Wrap around condition on phba->fcf.fcf_rr_bmask */
12171 if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX)
12172 next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask,
12173 LPFC_SLI4_FCF_TBL_INDX_MAX, 0);
12174 /* Round robin failover stop condition */
12175 if (next_fcf_index == phba->fcf.fcf_rr_init_indx)
12176 return LPFC_FCOE_FCF_NEXT_NONE;
12177
12178 return next_fcf_index;
12179}
12180
12181/**
12182 * lpfc_sli4_fcf_rr_index_set - Set bmask with eligible fcf record index
12183 * @phba: pointer to lpfc hba data structure.
12184 *
12185 * This routine sets the FCF record index in to the eligible bmask for
12186 * round robin failover search. It checks to make sure that the index
12187 * does not go beyond the range of the driver allocated bmask dimension
12188 * before setting the bit.
12189 *
12190 * Returns 0 if the index bit successfully set, otherwise, it returns
12191 * -EINVAL.
12192 **/
12193int
12194lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index)
12195{
12196 if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
12197 lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
12198 "2610 HBA FCF index reached driver's "
12199 "book keeping dimension: fcf_index:%d, "
12200 "driver_bmask_max:%d\n",
12201 fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
12202 return -EINVAL;
12203 }
12204 /* Set the eligible FCF record index bmask */
12205 set_bit(fcf_index, phba->fcf.fcf_rr_bmask);
12206
12207 return 0;
12208}
12209
12210/**
12211 * lpfc_sli4_fcf_rr_index_set - Clear bmask from eligible fcf record index
12212 * @phba: pointer to lpfc hba data structure.
12213 *
12214 * This routine clears the FCF record index from the eligible bmask for
12215 * round robin failover search. It checks to make sure that the index
12216 * does not go beyond the range of the driver allocated bmask dimension
12217 * before clearing the bit.
12218 **/
12219void
12220lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index)
12221{
12222 if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
12223 lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
12224 "2762 HBA FCF index goes beyond driver's "
12225 "book keeping dimension: fcf_index:%d, "
12226 "driver_bmask_max:%d\n",
12227 fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
12228 return;
12229 }
12230 /* Clear the eligible FCF record index bmask */
12231 clear_bit(fcf_index, phba->fcf.fcf_rr_bmask);
12232}
12233
12234/**
12052 * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table 12235 * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table
12053 * @phba: pointer to lpfc hba data structure. 12236 * @phba: pointer to lpfc hba data structure.
12054 * 12237 *
@@ -12069,13 +12252,13 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
12069 shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, 12252 shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
12070 &redisc_fcf->header.cfg_shdr.response); 12253 &redisc_fcf->header.cfg_shdr.response);
12071 if (shdr_status || shdr_add_status) { 12254 if (shdr_status || shdr_add_status) {
12072 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 12255 lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
12073 "2746 Requesting for FCF rediscovery failed " 12256 "2746 Requesting for FCF rediscovery failed "
12074 "status x%x add_status x%x\n", 12257 "status x%x add_status x%x\n",
12075 shdr_status, shdr_add_status); 12258 shdr_status, shdr_add_status);
12076 if (phba->fcf.fcf_flag & FCF_CVL_FOVER) { 12259 if (phba->fcf.fcf_flag & FCF_ACVL_DISC) {
12077 spin_lock_irq(&phba->hbalock); 12260 spin_lock_irq(&phba->hbalock);
12078 phba->fcf.fcf_flag &= ~FCF_CVL_FOVER; 12261 phba->fcf.fcf_flag &= ~FCF_ACVL_DISC;
12079 spin_unlock_irq(&phba->hbalock); 12262 spin_unlock_irq(&phba->hbalock);
12080 /* 12263 /*
12081 * CVL event triggered FCF rediscover request failed, 12264 * CVL event triggered FCF rediscover request failed,
@@ -12084,7 +12267,7 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
12084 lpfc_retry_pport_discovery(phba); 12267 lpfc_retry_pport_discovery(phba);
12085 } else { 12268 } else {
12086 spin_lock_irq(&phba->hbalock); 12269 spin_lock_irq(&phba->hbalock);
12087 phba->fcf.fcf_flag &= ~FCF_DEAD_FOVER; 12270 phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
12088 spin_unlock_irq(&phba->hbalock); 12271 spin_unlock_irq(&phba->hbalock);
12089 /* 12272 /*
12090 * DEAD FCF event triggered FCF rediscover request 12273 * DEAD FCF event triggered FCF rediscover request
@@ -12093,12 +12276,16 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
12093 */ 12276 */
12094 lpfc_sli4_fcf_dead_failthrough(phba); 12277 lpfc_sli4_fcf_dead_failthrough(phba);
12095 } 12278 }
12096 } else 12279 } else {
12280 lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
12281 "2775 Start FCF rediscovery quiescent period "
12282 "wait timer before scaning FCF table\n");
12097 /* 12283 /*
12098 * Start FCF rediscovery wait timer for pending FCF 12284 * Start FCF rediscovery wait timer for pending FCF
12099 * before rescan FCF record table. 12285 * before rescan FCF record table.
12100 */ 12286 */
12101 lpfc_fcf_redisc_wait_start_timer(phba); 12287 lpfc_fcf_redisc_wait_start_timer(phba);
12288 }
12102 12289
12103 mempool_free(mbox, phba->mbox_mem_pool); 12290 mempool_free(mbox, phba->mbox_mem_pool);
12104} 12291}
@@ -12117,6 +12304,9 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba)
12117 struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf; 12304 struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf;
12118 int rc, length; 12305 int rc, length;
12119 12306
12307 /* Cancel retry delay timers to all vports before FCF rediscover */
12308 lpfc_cancel_all_vport_retry_delay_timer(phba);
12309
12120 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 12310 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
12121 if (!mbox) { 12311 if (!mbox) {
12122 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 12312 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,