lpfc_attr.c

来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 1,504 行 · 第 1/3 页

C
1,504
字号
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);static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,			 lpfc_board_mode_show, lpfc_board_mode_store);static int lpfc_poll = 0;module_param(lpfc_poll, int, 0);MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"		 " 0 - none,"		 " 1 - poll with interrupts enabled"		 " 3 - poll and disable FCP ring interrupts");static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR,			 lpfc_poll_show, lpfc_poll_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.*/LPFC_ATTR_R(lun_queue_depth, 30, 1, 128,	    "Max number of FCP commands we can queue to a specific LUN");/*# hba_queue_depth:  This parameter is used to limit the number of outstanding# commands per lpfc HBA. Value range is [32,8192]. If this parameter# value is greater than the maximum number of exchanges supported by the HBA,# then maximum number of exchanges supported by the HBA is used to determine# the hba_queue_depth.*/LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192,	    "Max number of FCP commands we can queue to a lpfc HBA");/*# Some disk devices have a "select ID" or "select Target" capability.# From a protocol standpoint "select ID" usually means select the# Fibre channel "ALPA".  In the FC-AL Profile there is an "informative# annex" which contains a table that maps a "select ID" (a number# between 0 and 7F) to an ALPA.  By default, for compatibility with# older drivers, the lpfc driver scans this table from low ALPA to high# ALPA.## Turning on the scan-down variable (on  = 1, off = 0) will# cause the lpfc driver to use an inverted table, effectively# scanning ALPAs from high to low. Value range is [0,1]. Default value is 1.## (Note: This "select ID" functionality is a LOOP ONLY characteristic# and will not work across a fabric. Also this parameter will take# effect only in the case when ALPA map is not available.)*/LPFC_ATTR_R(scan_down, 1, 0, 1,	     "Start scanning for devices from highest ALPA to lowest");/*# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear# until the timer expires. Value range is [0,255]. Default value is 30.# NOTE: this MUST be less then the SCSI Layer command timeout - 1.*/LPFC_ATTR_RW(nodev_tmo, 30, 0, 255,	     "Seconds driver will hold I/O waiting for a device to come back");/*# lpfc_topology:  link topology for init link#            0x0  = attempt loop mode then point-to-point#            0x01 = internal loopback mode#            0x02 = attempt point-to-point mode only#            0x04 = attempt loop mode only#            0x06 = attempt point-to-point mode then loop# Set point-to-point mode if you want to run as an N_Port.# Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].# Default value is 0.*/LPFC_ATTR_RW(topology, 0, 0, 6, "Select Fibre Channel topology");/*# lpfc_link_speed: Link speed selection for initializing the Fibre Channel# connection.#       0  = auto select (default)#       1  = 1 Gigabaud#       2  = 2 Gigabaud#       4  = 4 Gigabaud# Value range is [0,4]. Default value is 0.*/LPFC_ATTR_R(link_speed, 0, 0, 4, "Select link speed");/*# lpfc_fcp_class:  Determines FC class to use for the FCP protocol.# Value range is [2,3]. Default value is 3.*/LPFC_ATTR_R(fcp_class, 3, 2, 3,	     "Select Fibre Channel class of service for FCP sequences");/*# lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range# is [0,1]. Default value is 0.*/LPFC_ATTR_RW(use_adisc, 0, 0, 1,	     "Use ADISC on rediscovery to authenticate FCP devices");/*# lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value# range is [0,1]. Default value is 0.*/LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");/*# lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing# cr_delay (msec) or cr_count outstanding commands. cr_delay can take# value [0,63]. cr_count can take value [0,255]. Default value of cr_delay# is 0. Default value of cr_count is 1. The cr_count feature is disabled if# cr_delay is set to 0.*/LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an "		"interrupt response is generated");LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "		"interrupt response is generated");/*# lpfc_multi_ring_support:  Determines how many rings to spread available# cmd/rsp IOCB entries across.# Value range is [1,2]. Default value is 1.*/LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "		"SLI rings to spread IOCB entries across");/*# lpfc_fdmi_on: controls FDMI support.#       0 = no FDMI support#       1 = support FDMI without attribute of hostname#       2 = support FDMI with attribute of hostname# Value range [0,2]. Default value is 0.*/LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");/*# Specifies the maximum number of ELS cmds we can have outstanding (for# discovery). Value range is [1,64]. Default value = 32.*/LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "		 "during discovery");/*# lpfc_max_luns: maximum number of LUNs per target driver will support# Value range is [1,32768]. Default value is 256.# NOTE: The SCSI layer will scan each target for this many luns*/LPFC_ATTR_R(max_luns, 256, 1, 32768,	     "Maximum number of LUNs per target driver will support");/*# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.# Value range is [1,255], default value is 10.*/LPFC_ATTR_RW(poll_tmo, 10, 1, 255,	     "Milliseconds driver will wait between polling FCP ring");struct class_device_attribute *lpfc_host_attrs[] = {	&class_device_attr_info,	&class_device_attr_serialnum,	&class_device_attr_modeldesc,	&class_device_attr_modelname,	&class_device_attr_programtype,	&class_device_attr_portnum,	&class_device_attr_fwrev,	&class_device_attr_hdw,	&class_device_attr_option_rom_version,	&class_device_attr_state,	&class_device_attr_num_discovered_ports,	&class_device_attr_lpfc_drvr_version,	&class_device_attr_lpfc_log_verbose,	&class_device_attr_lpfc_lun_queue_depth,	&class_device_attr_lpfc_hba_queue_depth,	&class_device_attr_lpfc_nodev_tmo,	&class_device_attr_lpfc_fcp_class,	&class_device_attr_lpfc_use_adisc,	&class_device_attr_lpfc_ack0,	&class_device_attr_lpfc_topology,	&class_device_attr_lpfc_scan_down,	&class_device_attr_lpfc_link_speed,	&class_device_attr_lpfc_cr_delay,	&class_device_attr_lpfc_cr_count,	&class_device_attr_lpfc_multi_ring_support,	&class_device_attr_lpfc_fdmi_on,	&class_device_attr_lpfc_max_luns,	&class_device_attr_nport_evt_cnt,	&class_device_attr_management_version,	&class_device_attr_board_online,	&class_device_attr_board_mode,	&class_device_attr_lpfc_poll,	&class_device_attr_lpfc_poll_tmo,	NULL,};static ssize_tsysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count){	size_t buf_off;	struct Scsi_Host *host = class_to_shost(container_of(kobj,					     struct class_device, kobj));	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;	if ((off + count) > FF_REG_AREA_SIZE)		return -ERANGE;	if (count == 0) return 0;	if (off % 4 || count % 4 || (unsigned long)buf % 4)		return -EINVAL;	spin_lock_irq(phba->host->host_lock);	if (!(phba->fc_flag & FC_OFFLINE_MODE)) {		spin_unlock_irq(phba->host->host_lock);		return -EPERM;	}	for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t))		writel(*((uint32_t *)(buf + buf_off)),		       phba->ctrl_regs_memmap_p + off + buf_off);	spin_unlock_irq(phba->host->host_lock);	return count;}static ssize_tsysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count){	size_t buf_off;	uint32_t * tmp_ptr;	struct Scsi_Host *host = class_to_shost(container_of(kobj,					     struct class_device, kobj));	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;	if (off > FF_REG_AREA_SIZE)		return -ERANGE;	if ((off + count) > FF_REG_AREA_SIZE)		count = FF_REG_AREA_SIZE - off;	if (count == 0) return 0;	if (off % 4 || count % 4 || (unsigned long)buf % 4)		return -EINVAL;	spin_lock_irq(phba->host->host_lock);	for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {		tmp_ptr = (uint32_t *)(buf + buf_off);		*tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);	}	spin_unlock_irq(phba->host->host_lock);	return count;}static struct bin_attribute sysfs_ctlreg_attr = {	.attr = {		.name = "ctlreg",		.mode = S_IRUSR | S_IWUSR,		.owner = THIS_MODULE,	},	.size = 256,	.read = sysfs_ctlreg_read,	.write = sysfs_ctlreg_write,};static voidsysfs_mbox_idle (struct lpfc_hba * phba){	phba->sysfs_mbox.state = SMBOX_IDLE;	phba->sysfs_mbox.offset = 0;	if (phba->sysfs_mbox.mbox) {		mempool_free(phba->sysfs_mbox.mbox,			     phba->mbox_mem_pool);		phba->sysfs_mbox.mbox = NULL;	}}static ssize_tsysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count){	struct Scsi_Host * host =		class_to_shost(container_of(kobj, struct class_device, kobj));	struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata;	struct lpfcMboxq * mbox = NULL;	if ((count + off) > MAILBOX_CMD_SIZE)		return -ERANGE;	if (off % 4 ||  count % 4 || (unsigned long)buf % 4)		return -EINVAL;	if (count == 0)		return 0;	if (off == 0) {		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);		if (!mbox)			return -ENOMEM;		memset(mbox, 0, sizeof (LPFC_MBOXQ_t));	}	spin_lock_irq(host->host_lock);	if (off == 0) {		if (phba->sysfs_mbox.mbox)			mempool_free(mbox, phba->mbox_mem_pool);		else			phba->sysfs_mbox.mbox = mbox;		phba->sysfs_mbox.state = SMBOX_WRITING;	} else {		if (phba->sysfs_mbox.state  != SMBOX_WRITING ||		    phba->sysfs_mbox.offset != off           ||		    phba->sysfs_mbox.mbox   == NULL ) {			sysfs_mbox_idle(phba);			spin_unlock_irq(host->host_lock);			return -EINVAL;		}	}	memcpy((uint8_t *) & phba->sysfs_mbox.mbox->mb + off,	       buf, count);	phba->sysfs_mbox.offset = off + count;	spin_unlock_irq(host->host_lock);	return count;}static ssize_tsysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count){	struct Scsi_Host *host =		class_to_shost(container_of(kobj, struct class_device,					    kobj));	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;	int rc;	if (off > sizeof(MAILBOX_t))		return -ERANGE;	if ((count + off) > sizeof(MAILBOX_t))		count = sizeof(MAILBOX_t) - off;	if (off % 4 ||  count % 4 || (unsigned long)buf % 4)		return -EINVAL;	if (off && count == 0)		return 0;	spin_lock_irq(phba->host->host_lock);	if (off == 0 &&	    phba->sysfs_mbox.state  == SMBOX_WRITING &&	    phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) {		switch (phba->sysfs_mbox.mbox->mb.mbxCommand) {			/* Offline only */		case MBX_WRITE_NV:		case MBX_INIT_LINK:		case MBX_DOWN_LINK:		case MBX_CONFIG_LINK:		case MBX_CONFIG_RING:		case MBX_RESET_RING:		case MBX_UNREG_LOGIN:		case MBX_CLEAR_LA:		case MBX_DUMP_CONTEXT:		case MBX_RUN_DIAGS:		case MBX_RESTART:		case MBX_FLASH_WR_ULA:		case MBX_SET_MASK:		case MBX_SET_SLIM:		case MBX_SET_DEBUG:			if (!(phba->fc_flag & FC_OFFLINE_MODE)) {				printk(KERN_WARNING "mbox_read:Command 0x%x "				       "is illegal in on-line state\n",				       phba->sysfs_mbox.mbox->mb.mbxCommand);				sysfs_mbox_idle(phba);				spin_unlock_irq(phba->host->host_lock);				return -EPERM;			}		case MBX_LOAD_SM:		case MBX_READ_NV:		case MBX_READ_CONFIG:		case MBX_READ_RCONFIG:		case MBX_READ_STATUS:		case MBX_READ_XRI:		case MBX_READ_REV:		case MBX_READ_LNK_STAT:		case MBX_DUMP_MEMORY:		case MBX_DOWN_LOAD:		case MBX_UPDATE_CFG:		case MBX_KILL_BOARD:		case MBX_LOAD_AREA:		case MBX_LOAD_EXP_ROM:		case MBX_BEACON:		case MBX_DEL_LD_ENTRY:			break;		case MBX_READ_SPARM64:		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->host->host_lock);			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->host->host_lock);			return -EPERM;		}		if ((phba->fc_flag & FC_OFFLINE_MODE) ||		    (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){			spin_unlock_irq(phba->host->host_lock);			rc = lpfc_sli_issue_mbox (phba,						  phba->sysfs_mbox.mbox,						  MBX_POLL);			spin_lock_irq(phba->host->host_lock);		} else {			spin_unlock_irq(phba->host->host_lock);			rc = lpfc_sli_issue_mbox_wait (phba,						       phba->sysfs_mbox.mbox,						       phba->fc_ratov * 2);			spin_lock_irq(phba->host->host_lock);		}		if (rc != MBX_SUCCESS) {			sysfs_mbox_idle(phba);			spin_unlock_irq(host->host_lock);			return -ENODEV;		}		phba->sysfs_mbox.state = SMBOX_READING;	}	else if (phba->sysfs_mbox.offset != off ||		 phba->sysfs_mbox.state  != SMBOX_READING) {

⌨️ 快捷键说明

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