diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 128 |
1 files changed, 91 insertions, 37 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 8d666d9fabb4..d2ddf7d9e1bb 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -11956,12 +11956,6 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) | |||
11956 | { | 11956 | { |
11957 | int rc = 0, error; | 11957 | int rc = 0, error; |
11958 | LPFC_MBOXQ_t *mboxq; | 11958 | LPFC_MBOXQ_t *mboxq; |
11959 | void *virt_addr; | ||
11960 | dma_addr_t phys_addr; | ||
11961 | uint8_t *bytep; | ||
11962 | struct lpfc_mbx_sge sge; | ||
11963 | uint32_t alloc_len, req_len; | ||
11964 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | ||
11965 | 11959 | ||
11966 | phba->fcoe_eventtag_at_fcf_scan = phba->fcoe_eventtag; | 11960 | phba->fcoe_eventtag_at_fcf_scan = phba->fcoe_eventtag; |
11967 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 11961 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
@@ -11972,43 +11966,19 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) | |||
11972 | error = -ENOMEM; | 11966 | error = -ENOMEM; |
11973 | goto fail_fcfscan; | 11967 | goto fail_fcfscan; |
11974 | } | 11968 | } |
11975 | 11969 | /* Construct the read FCF record mailbox command */ | |
11976 | req_len = sizeof(struct fcf_record) + | 11970 | rc = lpfc_sli4_mbx_read_fcf_record(phba, mboxq, fcf_index); |
11977 | sizeof(union lpfc_sli4_cfg_shdr) + 2 * sizeof(uint32_t); | 11971 | if (rc) { |
11978 | 11972 | error = -EINVAL; | |
11979 | /* Set up READ_FCF SLI4_CONFIG mailbox-ioctl command */ | ||
11980 | alloc_len = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
11981 | LPFC_MBOX_OPCODE_FCOE_READ_FCF_TABLE, req_len, | ||
11982 | LPFC_SLI4_MBX_NEMBED); | ||
11983 | |||
11984 | if (alloc_len < req_len) { | ||
11985 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11986 | "0291 Allocated DMA memory size (x%x) is " | ||
11987 | "less than the requested DMA memory " | ||
11988 | "size (x%x)\n", alloc_len, req_len); | ||
11989 | error = -ENOMEM; | ||
11990 | goto fail_fcfscan; | 11973 | goto fail_fcfscan; |
11991 | } | 11974 | } |
11992 | 11975 | /* Issue the mailbox command asynchronously */ | |
11993 | /* Get the first SGE entry from the non-embedded DMA memory. This | ||
11994 | * routine only uses a single SGE. | ||
11995 | */ | ||
11996 | lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); | ||
11997 | phys_addr = getPaddr(sge.pa_hi, sge.pa_lo); | ||
11998 | virt_addr = mboxq->sge_array->addr[0]; | ||
11999 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; | ||
12000 | |||
12001 | /* Set up command fields */ | ||
12002 | bf_set(lpfc_mbx_read_fcf_tbl_indx, &read_fcf->u.request, fcf_index); | ||
12003 | /* Perform necessary endian conversion */ | ||
12004 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
12005 | lpfc_sli_pcimem_bcopy(bytep, bytep, sizeof(uint32_t)); | ||
12006 | mboxq->vport = phba->pport; | 11976 | mboxq->vport = phba->pport; |
12007 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record; | 11977 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record; |
12008 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | 11978 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); |
12009 | if (rc == MBX_NOT_FINISHED) { | 11979 | if (rc == MBX_NOT_FINISHED) |
12010 | error = -EIO; | 11980 | error = -EIO; |
12011 | } else { | 11981 | else { |
12012 | spin_lock_irq(&phba->hbalock); | 11982 | spin_lock_irq(&phba->hbalock); |
12013 | phba->hba_flag |= FCF_DISC_INPROGRESS; | 11983 | phba->hba_flag |= FCF_DISC_INPROGRESS; |
12014 | spin_unlock_irq(&phba->hbalock); | 11984 | spin_unlock_irq(&phba->hbalock); |
@@ -12027,6 +11997,90 @@ fail_fcfscan: | |||
12027 | } | 11997 | } |
12028 | 11998 | ||
12029 | /** | 11999 | /** |
12000 | * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table | ||
12001 | * @phba: pointer to lpfc hba data structure. | ||
12002 | * | ||
12003 | * This routine is the completion routine for the rediscover FCF table mailbox | ||
12004 | * command. If the mailbox command returned failure, it will try to stop the | ||
12005 | * FCF rediscover wait timer. | ||
12006 | **/ | ||
12007 | void | ||
12008 | lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) | ||
12009 | { | ||
12010 | struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf; | ||
12011 | uint32_t shdr_status, shdr_add_status; | ||
12012 | |||
12013 | redisc_fcf = &mbox->u.mqe.un.redisc_fcf_tbl; | ||
12014 | |||
12015 | shdr_status = bf_get(lpfc_mbox_hdr_status, | ||
12016 | &redisc_fcf->header.cfg_shdr.response); | ||
12017 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
12018 | &redisc_fcf->header.cfg_shdr.response); | ||
12019 | if (shdr_status || shdr_add_status) { | ||
12020 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
12021 | "2746 Requesting for FCF rediscovery failed " | ||
12022 | "status x%x add_status x%x\n", | ||
12023 | shdr_status, shdr_add_status); | ||
12024 | /* | ||
12025 | * Request failed, last resort to re-try current | ||
12026 | * registered FCF entry | ||
12027 | */ | ||
12028 | lpfc_retry_pport_discovery(phba); | ||
12029 | } else | ||
12030 | /* | ||
12031 | * Start FCF rediscovery wait timer for pending FCF | ||
12032 | * before rescan FCF record table. | ||
12033 | */ | ||
12034 | lpfc_fcf_redisc_wait_start_timer(phba); | ||
12035 | |||
12036 | mempool_free(mbox, phba->mbox_mem_pool); | ||
12037 | } | ||
12038 | |||
12039 | /** | ||
12040 | * lpfc_sli4_redisc_all_fcf - Request to rediscover entire FCF table by port. | ||
12041 | * @phba: pointer to lpfc hba data structure. | ||
12042 | * | ||
12043 | * This routine is invoked to request for rediscovery of the entire FCF table | ||
12044 | * by the port. | ||
12045 | **/ | ||
12046 | int | ||
12047 | lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba) | ||
12048 | { | ||
12049 | LPFC_MBOXQ_t *mbox; | ||
12050 | struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf; | ||
12051 | int rc, length; | ||
12052 | |||
12053 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
12054 | if (!mbox) { | ||
12055 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
12056 | "2745 Failed to allocate mbox for " | ||
12057 | "requesting FCF rediscover.\n"); | ||
12058 | return -ENOMEM; | ||
12059 | } | ||
12060 | |||
12061 | length = (sizeof(struct lpfc_mbx_redisc_fcf_tbl) - | ||
12062 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
12063 | lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
12064 | LPFC_MBOX_OPCODE_FCOE_REDISCOVER_FCF, | ||
12065 | length, LPFC_SLI4_MBX_EMBED); | ||
12066 | |||
12067 | redisc_fcf = &mbox->u.mqe.un.redisc_fcf_tbl; | ||
12068 | /* Set count to 0 for invalidating the entire FCF database */ | ||
12069 | bf_set(lpfc_mbx_redisc_fcf_count, redisc_fcf, 0); | ||
12070 | |||
12071 | /* Issue the mailbox command asynchronously */ | ||
12072 | mbox->vport = phba->pport; | ||
12073 | mbox->mbox_cmpl = lpfc_mbx_cmpl_redisc_fcf_table; | ||
12074 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
12075 | |||
12076 | if (rc == MBX_NOT_FINISHED) { | ||
12077 | mempool_free(mbox, phba->mbox_mem_pool); | ||
12078 | return -EIO; | ||
12079 | } | ||
12080 | return 0; | ||
12081 | } | ||
12082 | |||
12083 | /** | ||
12030 | * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. | 12084 | * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. |
12031 | * @phba: pointer to lpfc hba data structure. | 12085 | * @phba: pointer to lpfc hba data structure. |
12032 | * | 12086 | * |