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 + -
显示快捷键?