qla_attr.c

来自「linux 内核源代码」· C语言 代码 · 共 1,253 行 · 第 1/3 页

C
1,253
字号
qla2x00_sysfs_read_sfp(struct kobject *kobj,		       struct bin_attribute *bin_attr,		       char *buf, loff_t off, size_t count){	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,	    struct device, kobj)));	uint16_t iter, addr, offset;	int rval;	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2)		return 0;	addr = 0xa0;	for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE;	    iter++, offset += SFP_BLOCK_SIZE) {		if (iter == 4) {			/* Skip to next device address. */			addr = 0xa2;			offset = 0;		}		rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset,		    SFP_BLOCK_SIZE);		if (rval != QLA_SUCCESS) {			qla_printk(KERN_WARNING, ha,			    "Unable to read SFP data (%x/%x/%x).\n", rval,			    addr, offset);			count = 0;			break;		}		memcpy(buf, ha->sfp_data, SFP_BLOCK_SIZE);		buf += SFP_BLOCK_SIZE;	}	return count;}static struct bin_attribute sysfs_sfp_attr = {	.attr = {		.name = "sfp",		.mode = S_IRUSR | S_IWUSR,	},	.size = SFP_DEV_SIZE * 2,	.read = qla2x00_sysfs_read_sfp,};static struct sysfs_entry {	char *name;	struct bin_attribute *attr;	int is4GBp_only;} bin_file_entries[] = {	{ "fw_dump", &sysfs_fw_dump_attr, },	{ "nvram", &sysfs_nvram_attr, },	{ "optrom", &sysfs_optrom_attr, },	{ "optrom_ctl", &sysfs_optrom_ctl_attr, },	{ "vpd", &sysfs_vpd_attr, 1 },	{ "sfp", &sysfs_sfp_attr, 1 },	{ NULL },};voidqla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha){	struct Scsi_Host *host = ha->host;	struct sysfs_entry *iter;	int ret;	for (iter = bin_file_entries; iter->name; iter++) {		if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))			continue;		ret = sysfs_create_bin_file(&host->shost_gendev.kobj,		    iter->attr);		if (ret)			qla_printk(KERN_INFO, ha,			    "Unable to create sysfs %s binary attribute "			    "(%d).\n", iter->name, ret);	}}voidqla2x00_free_sysfs_attr(scsi_qla_host_t *ha){	struct Scsi_Host *host = ha->host;	struct sysfs_entry *iter;	for (iter = bin_file_entries; iter->name; iter++) {		if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))			continue;		sysfs_remove_bin_file(&host->shost_gendev.kobj,		    iter->attr);	}	if (ha->beacon_blink_led == 1)		ha->isp_ops->beacon_off(ha);}/* Scsi_Host attributes. */static ssize_tqla2x00_drvr_version_show(struct class_device *cdev, char *buf){	return snprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str);}static ssize_tqla2x00_fw_version_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	char fw_str[30];	return snprintf(buf, PAGE_SIZE, "%s\n",	    ha->isp_ops->fw_version_str(ha, fw_str));}static ssize_tqla2x00_serial_num_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	uint32_t sn;	if (IS_FWI2_CAPABLE(ha))		return snprintf(buf, PAGE_SIZE, "\n");	sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;	return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000,	    sn % 100000);}static ssize_tqla2x00_isp_name_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device);}static ssize_tqla2x00_isp_id_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",	    ha->product_id[0], ha->product_id[1], ha->product_id[2],	    ha->product_id[3]);}static ssize_tqla2x00_model_name_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number);}static ssize_tqla2x00_model_desc_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	return snprintf(buf, PAGE_SIZE, "%s\n",	    ha->model_desc ? ha->model_desc: "");}static ssize_tqla2x00_pci_info_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	char pci_info[30];	return snprintf(buf, PAGE_SIZE, "%s\n",	    ha->isp_ops->pci_info_str(ha, pci_info));}static ssize_tqla2x00_state_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	int len = 0;	if (atomic_read(&ha->loop_state) == LOOP_DOWN ||	    atomic_read(&ha->loop_state) == LOOP_DEAD)		len = snprintf(buf, PAGE_SIZE, "Link Down\n");	else if (atomic_read(&ha->loop_state) != LOOP_READY ||	    test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) ||	    test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags))		len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");	else {		len = snprintf(buf, PAGE_SIZE, "Link Up - ");		switch (ha->current_topology) {		case ISP_CFG_NL:			len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");			break;		case ISP_CFG_FL:			len += snprintf(buf + len, PAGE_SIZE-len, "FL_Port\n");			break;		case ISP_CFG_N:			len += snprintf(buf + len, PAGE_SIZE-len,			    "N_Port to N_Port\n");			break;		case ISP_CFG_F:			len += snprintf(buf + len, PAGE_SIZE-len, "F_Port\n");			break;		default:			len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");			break;		}	}	return len;}static ssize_tqla2x00_zio_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	int len = 0;	switch (ha->zio_mode) {	case QLA_ZIO_MODE_6:		len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n");		break;	case QLA_ZIO_DISABLED:		len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n");		break;	}	return len;}static ssize_tqla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	int val = 0;	uint16_t zio_mode;	if (!IS_ZIO_SUPPORTED(ha))		return -ENOTSUPP;	if (sscanf(buf, "%d", &val) != 1)		return -EINVAL;	if (val)		zio_mode = QLA_ZIO_MODE_6;	else		zio_mode = QLA_ZIO_DISABLED;	/* Update per-hba values and queue a reset. */	if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) {		ha->zio_mode = zio_mode;		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);	}	return strlen(buf);}static ssize_tqla2x00_zio_timer_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100);}static ssize_tqla2x00_zio_timer_store(struct class_device *cdev, const char *buf,    size_t count){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	int val = 0;	uint16_t zio_timer;	if (sscanf(buf, "%d", &val) != 1)		return -EINVAL;	if (val > 25500 || val < 100)		return -ERANGE;	zio_timer = (uint16_t)(val / 100);	ha->zio_timer = zio_timer;	return strlen(buf);}static ssize_tqla2x00_beacon_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	int len = 0;	if (ha->beacon_blink_led)		len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n");	else		len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n");	return len;}static ssize_tqla2x00_beacon_store(struct class_device *cdev, const char *buf,    size_t count){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	int val = 0;	int rval;	if (IS_QLA2100(ha) || IS_QLA2200(ha))		return -EPERM;	if (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) {		qla_printk(KERN_WARNING, ha,		    "Abort ISP active -- ignoring beacon request.\n");		return -EBUSY;	}	if (sscanf(buf, "%d", &val) != 1)		return -EINVAL;	if (val)		rval = ha->isp_ops->beacon_on(ha);	else		rval = ha->isp_ops->beacon_off(ha);	if (rval != QLA_SUCCESS)		count = 0;	return count;}static ssize_tqla2x00_optrom_bios_version_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1],	    ha->bios_revision[0]);}static ssize_tqla2x00_optrom_efi_version_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1],	    ha->efi_revision[0]);}static ssize_tqla2x00_optrom_fcode_version_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1],	    ha->fcode_revision[0]);}static ssize_tqla2x00_optrom_fw_version_show(struct class_device *cdev, char *buf){	scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev));	return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n",	    ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2],	    ha->fw_revision[3]);}static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show,	NULL);static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);static CLASS_DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);static CLASS_DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL);static CLASS_DEVICE_ATTR(isp_id, S_IRUGO, qla2x00_isp_id_show, NULL);static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL);static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL);static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL);static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL);static CLASS_DEVICE_ATTR(zio, S_IRUGO | S_IWUSR, qla2x00_zio_show,    qla2x00_zio_store);static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show,    qla2x00_zio_timer_store);static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show,    qla2x00_beacon_store);static CLASS_DEVICE_ATTR(optrom_bios_version, S_IRUGO,    qla2x00_optrom_bios_version_show, NULL);static CLASS_DEVICE_ATTR(optrom_efi_version, S_IRUGO,    qla2x00_optrom_efi_version_show, NULL);static CLASS_DEVICE_ATTR(optrom_fcode_version, S_IRUGO,    qla2x00_optrom_fcode_version_show, NULL);static CLASS_DEVICE_ATTR(optrom_fw_version, S_IRUGO,    qla2x00_optrom_fw_version_show, NULL);struct class_device_attribute *qla2x00_host_attrs[] = {	&class_device_attr_driver_version,	&class_device_attr_fw_version,	&class_device_attr_serial_num,	&class_device_attr_isp_name,	&class_device_attr_isp_id,	&class_device_attr_model_name,	&class_device_attr_model_desc,	&class_device_attr_pci_info,	&class_device_attr_state,	&class_device_attr_zio,	&class_device_attr_zio_timer,	&class_device_attr_beacon,	&class_device_attr_optrom_bios_version,	&class_device_attr_optrom_efi_version,	&class_device_attr_optrom_fcode_version,	&class_device_attr_optrom_fw_version,	NULL,};/* Host attributes. */static voidqla2x00_get_host_port_id(struct Scsi_Host *shost){	scsi_qla_host_t *ha = shost_priv(shost);	fc_host_port_id(shost) = ha->d_id.b.domain << 16 |	    ha->d_id.b.area << 8 | ha->d_id.b.al_pa;}static voidqla2x00_get_host_speed(struct Scsi_Host *shost)

⌨️ 快捷键说明

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