欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

pdc_stable.c

linux 内核源代码
C
第 1 页 / 共 3 页
字号:
		return -ENODATA;		for (i = 0; devpath->layers[i] && (likely(i < 6)); i++)		out += sprintf(out, "%u ", devpath->layers[i]);	out += sprintf(out, "\n");		return out - buf;}/** * pdcspath_layer_write - This function handles extended layer modifying. * @entry: An allocated and populated pdscpath_entry struct. * @buf: The input buffer to read from. * @count: The number of bytes to be read. *  * We will call this function to change the current layer value. * Layers are to be given '.'-delimited, without brackets. * XXX beware we are far less checky WRT input data provided than for hwpath. * Potential harm can be done, since there's no way to check the validity of * the layer fields. */static ssize_tpdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count){	unsigned int layers[6]; /* device-specific info (ctlr#, unit#, ...) */	unsigned short i;	char in[count+1], *temp;	if (!entry || !buf || !count)		return -EINVAL;	/* We'll use a local copy of buf */	memset(in, 0, count+1);	strncpy(in, buf, count);		/* Let's clean up the target. 0 is a blank pattern */	memset(&layers, 0, sizeof(layers));		/* First, pick the first layer */	if (unlikely(!isdigit(*in)))		return -EINVAL;	layers[0] = simple_strtoul(in, NULL, 10);	DPRINTK("%s: layer[0]: %d\n", __func__, layers[0]);		temp = in;	for (i=1; ((temp = strchr(temp, '.'))) && (likely(i<6)); i++) {		if (unlikely(!isdigit(*(++temp))))			return -EINVAL;		layers[i] = simple_strtoul(temp, NULL, 10);		DPRINTK("%s: layer[%d]: %d\n", __func__, i, layers[i]);	}			/* So far so good, let's get in deep */	write_lock(&entry->rw_lock);		/* First, overwrite the current layers with the new ones, not touching	   the hardware path. */	memcpy(&entry->devpath.layers, &layers, sizeof(layers));		/* Now, dive in. Write back to the hardware */	pdcspath_store(entry);	write_unlock(&entry->rw_lock);		printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" layers to \"%s\"\n",		entry->name, buf);		return count;}/** * pdcspath_attr_show - Generic read function call wrapper. * @kobj: The kobject to get info from. * @attr: The attribute looked upon. * @buf: The output buffer. */static ssize_tpdcspath_attr_show(struct kobject *kobj, struct attribute *attr, char *buf){	struct pdcspath_entry *entry = to_pdcspath_entry(kobj);	struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr);	ssize_t ret = 0;	if (pdcs_attr->show)		ret = pdcs_attr->show(entry, buf);	return ret;}/** * pdcspath_attr_store - Generic write function call wrapper. * @kobj: The kobject to write info to. * @attr: The attribute to be modified. * @buf: The input buffer. * @count: The size of the buffer. */static ssize_tpdcspath_attr_store(struct kobject *kobj, struct attribute *attr,			const char *buf, size_t count){	struct pdcspath_entry *entry = to_pdcspath_entry(kobj);	struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr);	ssize_t ret = 0;	if (!capable(CAP_SYS_ADMIN))		return -EACCES;	if (pdcs_attr->store)		ret = pdcs_attr->store(entry, buf, count);	return ret;}static struct sysfs_ops pdcspath_attr_ops = {	.show = pdcspath_attr_show,	.store = pdcspath_attr_store,};/* These are the two attributes of any PDC path. */static PATHS_ATTR(hwpath, 0644, pdcspath_hwpath_read, pdcspath_hwpath_write);static PATHS_ATTR(layer, 0644, pdcspath_layer_read, pdcspath_layer_write);static struct attribute *paths_subsys_attrs[] = {	&paths_attr_hwpath.attr,	&paths_attr_layer.attr,	NULL,};/* Specific kobject type for our PDC paths */static struct kobj_type ktype_pdcspath = {	.sysfs_ops = &pdcspath_attr_ops,	.default_attrs = paths_subsys_attrs,};/* We hard define the 4 types of path we expect to find */static PDCSPATH_ENTRY(PDCS_ADDR_PPRI, primary);static PDCSPATH_ENTRY(PDCS_ADDR_PCON, console);static PDCSPATH_ENTRY(PDCS_ADDR_PALT, alternative);static PDCSPATH_ENTRY(PDCS_ADDR_PKBD, keyboard);/* An array containing all PDC paths we will deal with */static struct pdcspath_entry *pdcspath_entries[] = {	&pdcspath_entry_primary,	&pdcspath_entry_alternative,	&pdcspath_entry_console,	&pdcspath_entry_keyboard,	NULL,};/* For more insight of what's going on here, refer to PDC Procedures doc, * Section PDC_STABLE *//** * pdcs_size_read - Stable Storage size output. * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. */static ssize_tpdcs_size_read(struct kset *kset, char *buf){	char *out = buf;	if (!kset || !buf)		return -EINVAL;	/* show the size of the stable storage */	out += sprintf(out, "%ld\n", pdcs_size);	return out - buf;}/** * pdcs_auto_read - Stable Storage autoboot/search flag output. * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag */static ssize_tpdcs_auto_read(struct kset *kset, char *buf, int knob){	char *out = buf;	struct pdcspath_entry *pathentry;	if (!kset || !buf)		return -EINVAL;	/* Current flags are stored in primary boot path entry */	pathentry = &pdcspath_entry_primary;	read_lock(&pathentry->rw_lock);	out += sprintf(out, "%s\n", (pathentry->devpath.flags & knob) ?					"On" : "Off");	read_unlock(&pathentry->rw_lock);	return out - buf;}/** * pdcs_autoboot_read - Stable Storage autoboot flag output. * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. */static inline ssize_tpdcs_autoboot_read(struct kset *kset, char *buf){	return pdcs_auto_read(kset, buf, PF_AUTOBOOT);}/** * pdcs_autosearch_read - Stable Storage autoboot flag output. * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. */static inline ssize_tpdcs_autosearch_read(struct kset *kset, char *buf){	return pdcs_auto_read(kset, buf, PF_AUTOSEARCH);}/** * pdcs_timer_read - Stable Storage timer count output (in seconds). * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * * The value of the timer field correponds to a number of seconds in powers of 2. */static ssize_tpdcs_timer_read(struct kset *kset, char *buf){	char *out = buf;	struct pdcspath_entry *pathentry;	if (!kset || !buf)		return -EINVAL;	/* Current flags are stored in primary boot path entry */	pathentry = &pdcspath_entry_primary;	/* print the timer value in seconds */	read_lock(&pathentry->rw_lock);	out += sprintf(out, "%u\n", (pathentry->devpath.flags & PF_TIMER) ?				(1 << (pathentry->devpath.flags & PF_TIMER)) : 0);	read_unlock(&pathentry->rw_lock);	return out - buf;}/** * pdcs_osid_read - Stable Storage OS ID register output. * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. */static ssize_tpdcs_osid_read(struct kset *kset, char *buf){	char *out = buf;	if (!kset || !buf)		return -EINVAL;	out += sprintf(out, "%s dependent data (0x%.4x)\n",		os_id_to_string(pdcs_osid), pdcs_osid);	return out - buf;}/** * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output. * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * * This can hold 16 bytes of OS-Dependent data. */static ssize_tpdcs_osdep1_read(struct kset *kset, char *buf){	char *out = buf;	u32 result[4];	if (!kset || !buf)		return -EINVAL;	if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK)		return -EIO;	out += sprintf(out, "0x%.8x\n", result[0]);	out += sprintf(out, "0x%.8x\n", result[1]);	out += sprintf(out, "0x%.8x\n", result[2]);	out += sprintf(out, "0x%.8x\n", result[3]);	return out - buf;}/** * pdcs_diagnostic_read - Stable Storage Diagnostic register output. * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * * I have NFC how to interpret the content of that register ;-). */static ssize_tpdcs_diagnostic_read(struct kset *kset, char *buf){	char *out = buf;	u32 result;	if (!kset || !buf)		return -EINVAL;	/* get diagnostic */	if (pdc_stable_read(PDCS_ADDR_DIAG, &result, sizeof(result)) != PDC_OK)		return -EIO;	out += sprintf(out, "0x%.4x\n", (result >> 16));	return out - buf;}/** * pdcs_fastsize_read - Stable Storage FastSize register output. * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * * This register holds the amount of system RAM to be tested during boot sequence. */static ssize_tpdcs_fastsize_read(struct kset *kset, char *buf){	char *out = buf;	u32 result;	if (!kset || !buf)		return -EINVAL;	/* get fast-size */	if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK)		return -EIO;	if ((result & 0x0F) < 0x0E)		out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256);	else		out += sprintf(out, "All");	out += sprintf(out, "\n");		return out - buf;}/** * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output. * @kset: An allocated and populated struct kset. We don't use it tho. * @buf: The output buffer to write to. * * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available. */static ssize_tpdcs_osdep2_read(struct kset *kset, char *buf){	char *out = buf;	unsigned long size;	unsigned short i;	u32 result;	if (unlikely(pdcs_size <= 224))		return -ENODATA;	size = pdcs_size - 224;	if (!kset || !buf)		return -EINVAL;

⌨️ 快捷键说明

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