Linux Audio

Check our new training course

Loading...
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_NVRAM_H
#define _LINUX_NVRAM_H

#include <linux/errno.h>
#include <uapi/linux/nvram.h>

#ifdef CONFIG_PPC
#include <asm/machdep.h>
#endif

/**
 * struct nvram_ops - NVRAM functionality made available to drivers
 * @read: validate checksum (if any) then load a range of bytes from NVRAM
 * @write: store a range of bytes to NVRAM then update checksum (if any)
 * @read_byte: load a single byte from NVRAM
 * @write_byte: store a single byte to NVRAM
 * @get_size: return the fixed number of bytes in the NVRAM
 *
 * Architectures which provide an nvram ops struct need not implement all
 * of these methods. If the NVRAM hardware can be accessed only one byte
 * at a time then it may be sufficient to provide .read_byte and .write_byte.
 * If the NVRAM has a checksum (and it is to be checked) the .read and
 * .write methods can be used to implement that efficiently.
 *
 * Portable drivers may use the wrapper functions defined here.
 * The nvram_read() and nvram_write() functions call the .read and .write
 * methods when available and fall back on the .read_byte and .write_byte
 * methods otherwise.
 */

struct nvram_ops {
	ssize_t         (*get_size)(void);
	unsigned char   (*read_byte)(int);
	void            (*write_byte)(unsigned char, int);
	ssize_t         (*read)(char *, size_t, loff_t *);
	ssize_t         (*write)(char *, size_t, loff_t *);
#if defined(CONFIG_X86) || defined(CONFIG_M68K)
	long            (*initialize)(void);
	long            (*set_checksum)(void);
#endif
};

extern const struct nvram_ops arch_nvram_ops;

static inline ssize_t nvram_get_size(void)
{
#ifdef CONFIG_PPC
	if (ppc_md.nvram_size)
		return ppc_md.nvram_size();
#else
	if (arch_nvram_ops.get_size)
		return arch_nvram_ops.get_size();
#endif
	return -ENODEV;
}

static inline unsigned char nvram_read_byte(int addr)
{
#ifdef CONFIG_PPC
	if (ppc_md.nvram_read_val)
		return ppc_md.nvram_read_val(addr);
#else
	if (arch_nvram_ops.read_byte)
		return arch_nvram_ops.read_byte(addr);
#endif
	return 0xFF;
}

static inline void nvram_write_byte(unsigned char val, int addr)
{
#ifdef CONFIG_PPC
	if (ppc_md.nvram_write_val)
		ppc_md.nvram_write_val(addr, val);
#else
	if (arch_nvram_ops.write_byte)
		arch_nvram_ops.write_byte(val, addr);
#endif
}

static inline ssize_t nvram_read_bytes(char *buf, size_t count, loff_t *ppos)
{
	ssize_t nvram_size = nvram_get_size();
	loff_t i;
	char *p = buf;

	if (nvram_size < 0)
		return nvram_size;
	for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count)
		*p = nvram_read_byte(i);
	*ppos = i;
	return p - buf;
}

static inline ssize_t nvram_write_bytes(char *buf, size_t count, loff_t *ppos)
{
	ssize_t nvram_size = nvram_get_size();
	loff_t i;
	char *p = buf;

	if (nvram_size < 0)
		return nvram_size;
	for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count)
		nvram_write_byte(*p, i);
	*ppos = i;
	return p - buf;
}

static inline ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
{
#ifdef CONFIG_PPC
	if (ppc_md.nvram_read)
		return ppc_md.nvram_read(buf, count, ppos);
#else
	if (arch_nvram_ops.read)
		return arch_nvram_ops.read(buf, count, ppos);
#endif
	return nvram_read_bytes(buf, count, ppos);
}

static inline ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
{
#ifdef CONFIG_PPC
	if (ppc_md.nvram_write)
		return ppc_md.nvram_write(buf, count, ppos);
#else
	if (arch_nvram_ops.write)
		return arch_nvram_ops.write(buf, count, ppos);
#endif
	return nvram_write_bytes(buf, count, ppos);
}

#endif  /* _LINUX_NVRAM_H */
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy