lpfc_attr.c
来自「linux 内核源代码」· C语言 代码 · 共 2,217 行 · 第 1/5 页
C
2,217 行
case MBX_READ_LA: case MBX_READ_LA64: case MBX_REG_LOGIN: case MBX_REG_LOGIN64: case MBX_CONFIG_PORT: case MBX_RUN_BIU_DIAG: printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n", phba->sysfs_mbox.mbox->mb.mbxCommand); sysfs_mbox_idle(phba); spin_unlock_irq(&phba->hbalock); return -EPERM; default: printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n", phba->sysfs_mbox.mbox->mb.mbxCommand); sysfs_mbox_idle(phba); spin_unlock_irq(&phba->hbalock); return -EPERM; } phba->sysfs_mbox.mbox->vport = vport; if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { sysfs_mbox_idle(phba); spin_unlock_irq(&phba->hbalock); return -EAGAIN; } if ((vport->fc_flag & FC_OFFLINE_MODE) || (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){ spin_unlock_irq(&phba->hbalock); rc = lpfc_sli_issue_mbox (phba, phba->sysfs_mbox.mbox, MBX_POLL); spin_lock_irq(&phba->hbalock); } else { spin_unlock_irq(&phba->hbalock); rc = lpfc_sli_issue_mbox_wait (phba, phba->sysfs_mbox.mbox, lpfc_mbox_tmo_val(phba, phba->sysfs_mbox.mbox->mb.mbxCommand) * HZ); spin_lock_irq(&phba->hbalock); } if (rc != MBX_SUCCESS) { if (rc == MBX_TIMEOUT) { phba->sysfs_mbox.mbox = NULL; } sysfs_mbox_idle(phba); spin_unlock_irq(&phba->hbalock); return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV; } phba->sysfs_mbox.state = SMBOX_READING; } else if (phba->sysfs_mbox.offset != off || phba->sysfs_mbox.state != SMBOX_READING) { printk(KERN_WARNING "mbox_read: Bad State\n"); sysfs_mbox_idle(phba); spin_unlock_irq(&phba->hbalock); return -EAGAIN; } memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count); phba->sysfs_mbox.offset = off + count; if (phba->sysfs_mbox.offset == MAILBOX_CMD_SIZE) sysfs_mbox_idle(phba); spin_unlock_irq(&phba->hbalock); return count;}static struct bin_attribute sysfs_mbox_attr = { .attr = { .name = "mbox", .mode = S_IRUSR | S_IWUSR, }, .size = MAILBOX_CMD_SIZE, .read = sysfs_mbox_read, .write = sysfs_mbox_write,};intlpfc_alloc_sysfs_attr(struct lpfc_vport *vport){ struct Scsi_Host *shost = lpfc_shost_from_vport(vport); int error; error = sysfs_create_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr); if (error) goto out; error = sysfs_create_bin_file(&shost->shost_classdev.kobj, &sysfs_mbox_attr); if (error) goto out_remove_ctlreg_attr; return 0;out_remove_ctlreg_attr: sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr);out: return error;}voidlpfc_free_sysfs_attr(struct lpfc_vport *vport){ struct Scsi_Host *shost = lpfc_shost_from_vport(vport); sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_mbox_attr); sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr);}/* * Dynamic FC Host Attributes Support */static voidlpfc_get_host_port_id(struct Scsi_Host *shost){ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; /* note: fc_myDID already in cpu endianness */ fc_host_port_id(shost) = vport->fc_myDID;}static voidlpfc_get_host_port_type(struct Scsi_Host *shost){ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; spin_lock_irq(shost->host_lock); if (vport->port_type == LPFC_NPIV_PORT) { fc_host_port_type(shost) = FC_PORTTYPE_NPIV; } else if (lpfc_is_link_up(phba)) { if (phba->fc_topology == TOPOLOGY_LOOP) { if (vport->fc_flag & FC_PUBLIC_LOOP) fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; else fc_host_port_type(shost) = FC_PORTTYPE_LPORT; } else { if (vport->fc_flag & FC_FABRIC) fc_host_port_type(shost) = FC_PORTTYPE_NPORT; else fc_host_port_type(shost) = FC_PORTTYPE_PTP; } } else fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; spin_unlock_irq(shost->host_lock);}static voidlpfc_get_host_port_state(struct Scsi_Host *shost){ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; spin_lock_irq(shost->host_lock); if (vport->fc_flag & FC_OFFLINE_MODE) fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; else { switch (phba->link_state) { case LPFC_LINK_UNKNOWN: case LPFC_LINK_DOWN: fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; break; case LPFC_LINK_UP: case LPFC_CLEAR_LA: case LPFC_HBA_READY: /* Links up, beyond this port_type reports state */ fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; break; case LPFC_HBA_ERROR: fc_host_port_state(shost) = FC_PORTSTATE_ERROR; break; default: fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; break; } } spin_unlock_irq(shost->host_lock);}static voidlpfc_get_host_speed(struct Scsi_Host *shost){ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; spin_lock_irq(shost->host_lock); if (lpfc_is_link_up(phba)) { switch(phba->fc_linkspeed) { case LA_1GHZ_LINK: fc_host_speed(shost) = FC_PORTSPEED_1GBIT; break; case LA_2GHZ_LINK: fc_host_speed(shost) = FC_PORTSPEED_2GBIT; break; case LA_4GHZ_LINK: fc_host_speed(shost) = FC_PORTSPEED_4GBIT; break; case LA_8GHZ_LINK: fc_host_speed(shost) = FC_PORTSPEED_8GBIT; break; default: fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; break; } } spin_unlock_irq(shost->host_lock);}static voidlpfc_get_host_fabric_name (struct Scsi_Host *shost){ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; u64 node_name; spin_lock_irq(shost->host_lock); if ((vport->fc_flag & FC_FABRIC) || ((phba->fc_topology == TOPOLOGY_LOOP) && (vport->fc_flag & FC_PUBLIC_LOOP))) node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn); else /* fabric is local port if there is no F/FL_Port */ node_name = wwn_to_u64(vport->fc_nodename.u.wwn); spin_unlock_irq(shost->host_lock); fc_host_fabric_name(shost) = node_name;}static struct fc_host_statistics *lpfc_get_stats(struct Scsi_Host *shost){ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; struct lpfc_sli *psli = &phba->sli; struct fc_host_statistics *hs = &phba->link_stats; struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets; LPFC_MBOXQ_t *pmboxq; MAILBOX_t *pmb; unsigned long seconds; int rc = 0; /* * prevent udev from issuing mailbox commands until the port is * configured. */ if (phba->link_state < LPFC_LINK_DOWN || !phba->mbox_mem_pool || (phba->sli.sli_flag & LPFC_SLI2_ACTIVE) == 0) return NULL; if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) return NULL; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) return NULL; memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t)); pmb = &pmboxq->mb; pmb->mbxCommand = MBX_READ_STATUS; pmb->mbxOwner = OWN_HOST; pmboxq->context1 = NULL; pmboxq->vport = vport; if ((vport->fc_flag & FC_OFFLINE_MODE) || (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); else rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { if (rc != MBX_TIMEOUT) mempool_free(pmboxq, phba->mbox_mem_pool); return NULL; } memset(hs, 0, sizeof (struct fc_host_statistics)); hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt; hs->tx_words = (pmb->un.varRdStatus.xmitByteCnt * 256); hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt; hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256); memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t)); pmb->mbxCommand = MBX_READ_LNK_STAT; pmb->mbxOwner = OWN_HOST; pmboxq->context1 = NULL; pmboxq->vport = vport; if ((vport->fc_flag & FC_OFFLINE_MODE) || (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); else rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { if (rc != MBX_TIMEOUT) mempool_free(pmboxq, phba->mbox_mem_pool); return NULL; } hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt; hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt; hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt; hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord; hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt; hs->error_frames = pmb->un.varRdLnk.crcCnt; hs->link_failure_count -= lso->link_failure_count; hs->loss_of_sync_count -= lso->loss_of_sync_count; hs->loss_of_signal_count -= lso->loss_of_signal_count; hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count; hs->invalid_tx_word_count -= lso->invalid_tx_word_count; hs->invalid_crc_count -= lso->invalid_crc_count; hs->error_frames -= lso->error_frames; if (phba->fc_topology == TOPOLOGY_LOOP) { hs->lip_count = (phba->fc_eventTag >> 1); hs->lip_count -= lso->link_events; hs->nos_count = -1; } else { hs->lip_count = -1; hs->nos_count = (phba->fc_eventTag >> 1); hs->nos_count -= lso->link_events; } hs->dumped_frames = -1; seconds = get_seconds(); if (seconds < psli->stats_start) hs->seconds_since_last_reset = seconds + ((unsigned long)-1 - psli->stats_start); else hs->seconds_since_last_reset = seconds - psli->stats_start; mempool_free(pmboxq, phba->mbox_mem_pool); return hs;}static voidlpfc_reset_stats(struct Scsi_Host *shost){ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; struct lpfc_sli *psli = &phba->sli; struct lpfc_lnk_stat *lso = &psli->lnk_stat_offsets; LPFC_MBOXQ_t *pmboxq; MAILBOX_t *pmb; int rc = 0; if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) return; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) return; memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); pmb = &pmboxq->mb; pmb->mbxCommand = MBX_READ_STATUS; pmb->mbxOwner = OWN_HOST; pmb->un.varWords[0] = 0x1; /* reset request */ pmboxq->context1 = NULL; pmboxq->vport = vport; if ((vport->fc_flag & FC_OFFLINE_MODE) || (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); else rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { if (rc != MBX_TIMEOUT) mempool_free(pmboxq, phba->mbox_mem_pool); return; } memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); pmb->mbxCommand = MBX_READ_LNK_STAT; pmb->mbxOwner = OWN_HOST; pmboxq->context1 = NULL; pmboxq->vport = vport; if ((vport->fc_flag & FC_OFFLINE_MODE) || (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); else rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if (rc != MBX_SUCCESS) { if (rc != MBX_TIMEOUT) mempool_free( pmboxq, phba->mbox_mem_pool); return; } lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt; lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt; lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt; lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord; lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt; lso->error_frames = pmb->un.varRdLnk.crcCnt; lso->link_events = (phba->fc_eventTag >> 1); psli->stats_start = get_seconds(); mempool_free(pmboxq, phba->mbox_mem_pool); return;}/* * The LPFC driver treats linkdown handling as target loss events so there * are no sysfs handlers for link_down_tmo. */static struct lpfc_nodelist *lpfc_get_node_by_target(struct scsi_target *starget){ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct lpfc_vport *vport
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?