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

📄 lpfc_attr.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
*/LPFC_ATTR_R(lun_queue_depth, 30, 1, 128,	    "Max number of FCP commands we can queue to a specific LUN");/*# 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#            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_R(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(cr_delay, 0, 0, 63, "A count of milliseconds after which an"		"interrupt response is generated");LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an"		"interrupt response is generated");/*# 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");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_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_fdmi_on,	&class_device_attr_lpfc_max_luns,	&class_device_attr_nport_evt_cnt,	&class_device_attr_management_version,	&class_device_attr_board_online,	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[0];	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[0];	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[0];	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;	}	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[0];	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_LOAD_AREA:		case MBX_LOAD_EXP_ROM:			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) {		printk(KERN_WARNING  "mbox_read: Bad State\n");		sysfs_mbox_idle(phba);		spin_unlock_irq(host->host_lock);		return -EINVAL;	}	memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count);	phba->sysfs_mbox.offset = off + count;	if (phba->sysfs_mbox.offset == sizeof(MAILBOX_t))		sysfs_mbox_idle(phba);	spin_unlock_irq(phba->host->host_lock);	return count;}static struct bin_attribute sysfs_mbox_attr = {	.attr = {		.name = "mbox",		.mode = S_IRUSR | S_IWUSR,		.owner = THIS_MODULE,	},	.size = sizeof(MAILBOX_t),	.read = sysfs_mbox_read,	.write = sysfs_mbox_write,};intlpfc_alloc_sysfs_attr(struct lpfc_hba *phba){	struct Scsi_Host *host = phba->host;	int error;	error = sysfs_create_bin_file(&host->shost_classdev.kobj,							&sysfs_ctlreg_attr);	if (error)		goto out;	error = sysfs_create_bin_file(&host->shost_classdev.kobj,							&sysfs_mbox_attr);	if (error)		goto out_remove_ctlreg_attr;	return 0;out_remove_ctlreg_attr:	sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr);

⌨️ 快捷键说明

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