⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpfc_attr.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************* * This file is part of the Emulex Linux Device Driver for         * * Fibre Channel Host Bus Adapters.                                * * Copyright (C) 2004-2005 Emulex.  All rights reserved.           * * EMULEX and SLI are trademarks of Emulex.                        * * www.emulex.com                                                  * * Portions Copyright (C) 2004-2005 Christoph Hellwig              * *                                                                 * * This program is free software; you can redistribute it and/or   * * modify it under the terms of version 2 of the GNU General       * * Public License as published by the Free Software Foundation.    * * This program is distributed in the hope that it will be useful. * * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          * * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  * * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      * * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * * TO BE LEGALLY INVALID.  See the GNU General Public License for  * * more details, a copy of which can be found in the file COPYING  * * included with this package.                                     * *******************************************************************/#include <linux/ctype.h>#include <linux/pci.h>#include <linux/interrupt.h>#include <scsi/scsi.h>#include <scsi/scsi_device.h>#include <scsi/scsi_host.h>#include <scsi/scsi_tcq.h>#include <scsi/scsi_transport_fc.h>#include "lpfc_hw.h"#include "lpfc_sli.h"#include "lpfc_disc.h"#include "lpfc_scsi.h"#include "lpfc.h"#include "lpfc_logmsg.h"#include "lpfc_version.h"#include "lpfc_compat.h"#include "lpfc_crtn.h"static voidlpfc_jedec_to_ascii(int incr, char hdw[]){	int i, j;	for (i = 0; i < 8; i++) {		j = (incr & 0xf);		if (j <= 9)			hdw[7 - i] = 0x30 +  j;		 else			hdw[7 - i] = 0x61 + j - 10;		incr = (incr >> 4);	}	hdw[8] = 0;	return;}static ssize_tlpfc_drvr_version_show(struct class_device *cdev, char *buf){	return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n");}static ssize_tmanagement_version_show(struct class_device *cdev, char *buf){	return snprintf(buf, PAGE_SIZE, DFC_API_VERSION "\n");}static ssize_tlpfc_info_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host));}static ssize_tlpfc_serialnum_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber);}static ssize_tlpfc_modeldesc_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc);}static ssize_tlpfc_modelname_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName);}static ssize_tlpfc_programtype_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType);}static ssize_tlpfc_portnum_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port);}static ssize_tlpfc_fwrev_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	char fwrev[32];	lpfc_decode_firmware_rev(phba, fwrev, 1);	return snprintf(buf, PAGE_SIZE, "%s\n",fwrev);}static ssize_tlpfc_hdw_show(struct class_device *cdev, char *buf){	char hdw[9];	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	lpfc_vpd_t *vp = &phba->vpd;	lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);	return snprintf(buf, PAGE_SIZE, "%s\n", hdw);}static ssize_tlpfc_option_rom_version_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion);}static ssize_tlpfc_state_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	int len = 0;	switch (phba->hba_state) {	case LPFC_INIT_START:	case LPFC_INIT_MBX_CMDS:	case LPFC_LINK_DOWN:		len += snprintf(buf + len, PAGE_SIZE-len, "Link Down\n");		break;	case LPFC_LINK_UP:	case LPFC_LOCAL_CFG_LINK:		len += snprintf(buf + len, PAGE_SIZE-len, "Link Up\n");		break;	case LPFC_FLOGI:	case LPFC_FABRIC_CFG_LINK:	case LPFC_NS_REG:	case LPFC_NS_QRY:	case LPFC_BUILD_DISC_LIST:	case LPFC_DISC_AUTH:	case LPFC_CLEAR_LA:		len += snprintf(buf + len, PAGE_SIZE-len,				"Link Up - Discovery\n");		break;	case LPFC_HBA_READY:		len += snprintf(buf + len, PAGE_SIZE-len,				"Link Up - Ready:\n");		if (phba->fc_topology == TOPOLOGY_LOOP) {			if (phba->fc_flag & FC_PUBLIC_LOOP)				len += snprintf(buf + len, PAGE_SIZE-len,						"   Public Loop\n");			else				len += snprintf(buf + len, PAGE_SIZE-len,						"   Private Loop\n");		} else {			if (phba->fc_flag & FC_FABRIC)				len += snprintf(buf + len, PAGE_SIZE-len,						"   Fabric\n");			else				len += snprintf(buf + len, PAGE_SIZE-len,						"   Point-2-Point\n");		}	}	return len;}static ssize_tlpfc_num_discovered_ports_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt +							phba->fc_unmap_cnt);}static intlpfc_issue_lip(struct Scsi_Host *host){	struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];	LPFC_MBOXQ_t *pmboxq;	int mbxstatus = MBXERR_ERROR;	if ((phba->fc_flag & FC_OFFLINE_MODE) ||	    (phba->hba_state != LPFC_HBA_READY))		return -EPERM;	pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);	if (!pmboxq)		return -ENOMEM;	memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));	lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed);	mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);	if (mbxstatus == MBX_TIMEOUT)		pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;	else		mempool_free(pmboxq, phba->mbox_mem_pool);	if (mbxstatus == MBXERR_ERROR)		return -EIO;	return 0;}static ssize_tlpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);}static ssize_tlpfc_board_online_show(struct class_device *cdev, char *buf){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	if (phba->fc_flag & FC_OFFLINE_MODE)		return snprintf(buf, PAGE_SIZE, "0\n");	else		return snprintf(buf, PAGE_SIZE, "1\n");}static ssize_tlpfc_board_online_store(struct class_device *cdev, const char *buf,								size_t count){	struct Scsi_Host *host = class_to_shost(cdev);	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];	struct completion online_compl;	int val=0, status=0;	if (sscanf(buf, "%d", &val) != 1)		return -EINVAL;	init_completion(&online_compl);	if (val)		lpfc_workq_post_event(phba, &status, &online_compl,							LPFC_EVT_ONLINE);	else		lpfc_workq_post_event(phba, &status, &online_compl,							LPFC_EVT_OFFLINE);	wait_for_completion(&online_compl);	if (!status)		return strlen(buf);	else		return -EIO;}#define lpfc_param_show(attr)	\static ssize_t \lpfc_##attr##_show(struct class_device *cdev, char *buf) \{ \	struct Scsi_Host *host = class_to_shost(cdev);\	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\	int val = 0;\	val = phba->cfg_##attr;\	return snprintf(buf, PAGE_SIZE, "%d\n",\			phba->cfg_##attr);\}#define lpfc_param_hex_show(attr)	\static ssize_t \lpfc_##attr##_show(struct class_device *cdev, char *buf) \{ \	struct Scsi_Host *host = class_to_shost(cdev);\	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\	int val = 0;\	val = phba->cfg_##attr;\	return snprintf(buf, PAGE_SIZE, "%#x\n",\			phba->cfg_##attr);\}#define lpfc_param_init(attr, default, minval, maxval)	\static int \lpfc_##attr##_init(struct lpfc_hba *phba, int val) \{ \	if (val >= minval && val <= maxval) {\		phba->cfg_##attr = val;\		return 0;\	}\	lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \			"%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\			"allowed range is ["#minval", "#maxval"]\n", \			phba->brd_no, val); \	phba->cfg_##attr = default;\	return -EINVAL;\}#define lpfc_param_set(attr, default, minval, maxval)	\static int \lpfc_##attr##_set(struct lpfc_hba *phba, int val) \{ \	if (val >= minval && val <= maxval) {\		phba->cfg_##attr = val;\		return 0;\	}\	lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \			"%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\			"allowed range is ["#minval", "#maxval"]\n", \			phba->brd_no, val); \	return -EINVAL;\}#define lpfc_param_store(attr)	\static ssize_t \lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \{ \	struct Scsi_Host *host = class_to_shost(cdev);\	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\	int val=0;\	if (!isdigit(buf[0]))\		return -EINVAL;\	if (sscanf(buf, "%i", &val) != 1)\		return -EINVAL;\	if (lpfc_##attr##_set(phba, val) == 0) \		return strlen(buf);\	else \		return -EINVAL;\}#define LPFC_ATTR(name, defval, minval, maxval, desc) \static int lpfc_##name = defval;\module_param(lpfc_##name, int, 0);\MODULE_PARM_DESC(lpfc_##name, desc);\lpfc_param_init(name, defval, minval, maxval)#define LPFC_ATTR_R(name, defval, minval, maxval, desc) \static int lpfc_##name = defval;\module_param(lpfc_##name, int, 0);\MODULE_PARM_DESC(lpfc_##name, desc);\lpfc_param_show(name)\lpfc_param_init(name, defval, minval, maxval)\static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)#define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \static int lpfc_##name = defval;\module_param(lpfc_##name, int, 0);\MODULE_PARM_DESC(lpfc_##name, desc);\lpfc_param_show(name)\lpfc_param_init(name, defval, minval, maxval)\lpfc_param_set(name, defval, minval, maxval)\lpfc_param_store(name)\static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\			 lpfc_##name##_show, lpfc_##name##_store)#define LPFC_ATTR_HEX_R(name, defval, minval, maxval, desc) \static int lpfc_##name = defval;\module_param(lpfc_##name, int, 0);\MODULE_PARM_DESC(lpfc_##name, desc);\lpfc_param_hex_show(name)\lpfc_param_init(name, defval, minval, maxval)\static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)#define LPFC_ATTR_HEX_RW(name, defval, minval, maxval, desc) \static int lpfc_##name = defval;\module_param(lpfc_##name, int, 0);\MODULE_PARM_DESC(lpfc_##name, desc);\lpfc_param_hex_show(name)\lpfc_param_init(name, defval, minval, maxval)\lpfc_param_set(name, defval, minval, maxval)\lpfc_param_store(name)\static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\			 lpfc_##name##_show, lpfc_##name##_store)static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);static CLASS_DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL);static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_portnum_show, NULL);static CLASS_DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);static CLASS_DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);static CLASS_DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL);static CLASS_DEVICE_ATTR(option_rom_version, S_IRUGO,					lpfc_option_rom_version_show, NULL);static CLASS_DEVICE_ATTR(num_discovered_ports, S_IRUGO,					lpfc_num_discovered_ports_show, NULL);static CLASS_DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,			 NULL);static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,			 NULL);static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,			 lpfc_board_online_show, lpfc_board_online_store);/*# lpfc_log_verbose: Only turn this flag on if you are willing to risk being# deluged with LOTS of information.# You can set a bit mask to record specific types of verbose messages:## LOG_ELS                       0x1        ELS events# LOG_DISCOVERY                 0x2        Link discovery events# LOG_MBOX                      0x4        Mailbox events# LOG_INIT                      0x8        Initialization events# LOG_LINK_EVENT                0x10       Link events# LOG_IP                        0x20       IP traffic history# LOG_FCP                       0x40       FCP traffic history# LOG_NODE                      0x80       Node table events# LOG_MISC                      0x400      Miscellaneous events# LOG_SLI                       0x800      SLI events# LOG_CHK_COND                  0x1000     FCP Check condition flag# LOG_LIBDFC                    0x2000     LIBDFC events# LOG_ALL_MSG                   0xffff     LOG all messages*/LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");/*# lun_queue_depth:  This parameter is used to limit the number of outstanding# commands per FCP LUN. Value range is [1,128]. Default value is 30.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -